2017-02-23 38 views
0

我不能为上帝的爱解决这个问题。我看到了这个答案:How to Bind data to DataGridComboBoxColumn in DataGrid using MVVM和更多的事情,但我不知道我做错了什么。这是我的想法。我有一个DataGrid,它将绑定到Views集合。每行由类ViewWrapper的对象表示。ViewWrapper具有名为ViewTemplate的属性,其类型为ViewWrapper。所以基本上看,包装器可以在其中存储另一个视图包装器。现在,我想将ComboBox连接到存储在名为ViewTemplates的变量中的ViewWrapper对象列表中。这在ViewModel上可用。它包含View模板属性可能设置的所有可能的视图包装。现在,我想将ComboBox的SelectedItem绑定到DataGrid行的ViewWrapper.ViewTemplate。我无法得到这个东西的工作。Combobox Column在WPVM中与MVVM模式(Galasoft)

这里是我的设置:

XAML:

<UserControl x:Class="GrimshawRibbon.Revit.Views.ViewManager.ViewManagerView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
      xmlns:local="clr-namespace:GrimshawRibbon.Revit.Views.ViewManager" 
      xmlns:ex="clr-namespace:GrimshawRibbon.Revit.Wpf.Extensions" 
      xmlns:controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" 
      xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Platform" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="500"> 
    <UserControl.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" /> 
       <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" /> 
       <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" /> 
       <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" /> 
       <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" /> 
       <ResourceDictionary Source="pack://application:,,,/GrimshawRibbon;component/Revit/Wpf/Style/GrimshawTheme.xaml"/> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary> 
    </UserControl.Resources> 
    <Grid> 
     <ex:DataGridEx x:Name="dgViews" 
           Style="{StaticResource AzureDataGrid}" 
           Margin="10" 
           AutoGenerateColumns="False" 
           ItemsSource="{Binding Views, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
           CanUserAddRows="False" 
           IsReadOnly="False" 
           SelectionMode="Extended" 
           SelectionUnit="FullRow" 
           SelectedItemsList="{Binding SelectedViews, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> 
      <i:Interaction.Triggers> 
       <i:EventTrigger EventName="CellEditEnding"> 
        <cmd:EventToCommand PassEventArgsToCommand="True" Command="{Binding CellEditEndingCommand}"/> 
       </i:EventTrigger> 
      </i:Interaction.Triggers> 
      <DataGrid.Columns> 
       <DataGridTextColumn Header="Name" Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="*"/> 
       <DataGridTextColumn Header="ViewType" Binding="{Binding ViewType}" Width="100" IsReadOnly="True"/> 
       <DataGridTextColumn Header="ViewGroup" Binding="{Binding ViewGroup, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="120" IsReadOnly="False"/> 
       <DataGridTextColumn Header="ViewSubGroup" Binding="{Binding ViewSubGroup, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="120" IsReadOnly="False"/> 
       <DataGridCheckBoxColumn ElementStyle="{DynamicResource MetroDataGridCheckBox}" 
             EditingElementStyle="{DynamicResource MetroDataGridCheckBox}" 
             Header="OnSheet" 
             Binding="{Binding OnSheet, Mode=TwoWay}" 
             IsReadOnly="True" 
             Width="80"> 
       </DataGridCheckBoxColumn> 
       <DataGridComboBoxColumn Header="ViewTemplate" Width="150" SelectedItemBinding="{Binding WhatDoISetThisTo?}"> 
        <DataGridComboBoxColumn.ElementStyle> 
         <Style TargetType="ComboBox"> 
          <Setter Property="ItemsSource" Value="{Binding ViewTemplates}"/> 
          <Setter Property="IsReadOnly" Value="True"/> 
         </Style> 
        </DataGridComboBoxColumn.ElementStyle> 
        <DataGridComboBoxColumn.EditingElementStyle> 
         <Style TargetType="ComboBox"> 
          <Setter Property="ItemsSource" Value="{Binding ViewTemplates}"/> 
         </Style> 
        </DataGridComboBoxColumn.EditingElementStyle> 
       </DataGridComboBoxColumn> 
      </DataGrid.Columns> 
     </ex:DataGridEx> 
    </Grid> 
</UserControl> 

视图模型:

public class ViewManagerViewModel : ViewModelBaseEx 
    { 
     public ViewManagerModel Model; 
     public ObservableCollection<ViewWrapper> Views { get; private set; } 
     public ObservableCollection<ViewWrapper> ViewTemplates { get; private set; } 
     public IList SelectedViews { get; set; } 
     public RelayCommand<DataGridCellEditEndingEventArgs> CellEditEndingCommand { get; set; } 

     public ViewManagerViewModel(Document doc) 
     { 
      Model = new ViewManagerModel(doc); 
      Views = Model.CollectViews(); 
      ViewTemplates = Model.CollectViewTemplates(); 
      CellEditEndingCommand = new RelayCommand<DataGridCellEditEndingEventArgs>(args => OnCellEditEnding(args)); 
     } 

     /// <summary> 
     /// Logic for handling cell editing events. 
     /// </summary> 
     /// <param name="e">DataGrid Row object.</param> 
     private void OnCellEditEnding(DataGridCellEditEndingEventArgs e) 
     { 
      var wrapper = e.Row.Item as ViewWrapper; 
      switch (e.Column.SortMemberPath) 
      { 
       case "Name": 
        Model.ChangeName(wrapper); 
        break; 
       case "ViewGroup": 
        Model.SetParameter(wrapper, "View Group", wrapper.ViewGroup); 
        break; 
       case "ViewSubGroup": 
        Model.SetParameter(wrapper, "View Sub Group", wrapper.ViewSubGroup); 
        break; 
       default: 
        break; 
      } 
     } 

     public override void Apply() 
     { 
      var vw = new List<ViewWrapper>(); 
      foreach (ViewWrapper v in SelectedViews) 
      { 
       vw.Add(v); 
      } 

      Model.Delete(vw); 

      // update collection so that rows get deleted in datagrid 
      foreach (ViewWrapper i in vw) 
      { 
       Views.Remove(i); 
      } 
     } 
    } 

ViewWrapper类:

public abstract class ElementWrapper : ObservableObject 
    { 
     public virtual object Self { get; set; } 
     public virtual ElementId ID { get; set; } 
     public virtual string Name { get; set; } 
    } 



    public class ViewWrapper : ElementWrapper 
    { 
     public string ViewType { get; set; } 
     public bool IsSelected { get; set; } 
     public bool OnSheet { get; set; } 
     public string ViewGroup { get; set; } 
     public string ViewSubGroup { get; set; } 
     public ViewWrapper ViewTemplate { get; set; } 

    } 

回答

1

SelectedItemBinding属性应该是绑定到表示当前行的ViewWrapper对象的ViewTemplate属性。

而且由于在视图模型中定义了ViewTemplates集合,所以应该使用绑定来绑定它。

试试这个:

<DataGridComboBoxColumn Header="ViewTemplate" Width="150" SelectedItemBinding="{Binding ViewTemplate}"> 
    <DataGridComboBoxColumn.ElementStyle> 
     <Style TargetType="ComboBox"> 
      <Setter Property="ItemsSource" Value="{Binding DataContext.ViewTemplates, RelativeSource={RelativeSource AncestorType=DataGrid}}"/> 
      <Setter Property="IsReadOnly" Value="True"/> 
     </Style> 
    </DataGridComboBoxColumn.ElementStyle> 
    <DataGridComboBoxColumn.EditingElementStyle> 
     <Style TargetType="ComboBox"> 
      <Setter Property="ItemsSource" Value="{Binding DataContext.ViewTemplates, RelativeSource={RelativeSource AncestorType=DataGrid}}"/> 
     </Style> 
    </DataGridComboBoxColumn.EditingElementStyle> 
</DataGridComboBoxColumn> 
+0

这只是让我有一部分。我现在可以在我的下拉列表中看到所有“ViewTemplates”,但没有选择任何值。某些行项目已经具有分配ViewTemplate的值,在这种情况下,当组合框的选定项目被绑定到它时,它应该从下拉菜单中设置适当的值。对? – konrad

+0

这取决于如何设置ViewTemplate属性。您需要设置视图模型的ViewTemplates集合中存在的ViewWrapper实例。 – mm8

+0

好吧,他们是同一班。如果我重写那个包装类的'Equals'方法呢?这是否会告诉它,他们是每个说的相同的实例,因为是的,他们都是分别实例化,所以我可以看到它是如何认为他们不是同一个对象。 – konrad