根据DataGrid项

时间:2016-09-29 13:00:02

标签: c# wpf mvvm combobox

在我的应用程序中,我使用的是C#,WPF,我正在遵循MVVM模式。

我想要实现的目标如下:

我有一个DataGridItemSource在我的ViewModel中Collection<MyObject>上。 MyObject有两个enum属性,TypeA和TypeB(TypeA是与TypeB不同的枚举类型)。

enum TypeA {one, two, three}
enum TypeB {a, b, c, d, e, f, g}

DataGrid的每一行都有ComboBox,用户可以通过选择其中一个可用值来更改TypeB值。用户无法更改TypeA。但是,TypeB的可用值基于TypeA的值。

<DataGridTemplateColumn Header="Type B">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox SelectedItem="{Binding TypeB, UpdateSourceTrigger=PropertyChanged}">
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Converter={StaticResource DescriptionConverter}}"/>
                    </DataTemplate>
                 </ComboBox.ItemTemplate>
             </ComboBox>
         </DataTemplate>
     </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

假设可以使用以下规则找到可用的TypeB值:

  

如果Type = 1,则TypeB可用值为{a,b,c,d}
  如果Type = 2,则TypeB可用值为{d,e,f,g}
  如果Type = 3,则TypeB可用值为{a,b,f,g}

我正在尝试将此逻辑复制到DataGrid,我遵循以下方法。然而,其中一些不起作用,而另一些'打破'MVVM模式。有什么想法或建议吗?

  1. 将ComboBox绑定到dynamic ItemSource
    所以在我的组合框中我有类似

    的东西
    <ComboBox ItemsSource="{Binding TypeBAvailable}"
    

    并在视图模型中

    public ICollectionView AvailableTypeB
    {
        get
        {
            ObservableCollection<TypeB> availableTypeB = new ObservableCollection<TypeB>((TypeB[])Enum.GetValues(typeof(TypeB)));
    
            // Here based on the TypeA property of the SelectedRow in the grid 
            // I am populating the availableTypeB collection with the needed values based on the aforementioned rules
    
            return CollectionViewSource.GetDefaultView(availableTypeB);
        }
    }
    

    * SelectedRow是一个与DataGrid的SelectedItem绑定的项目。

    我还尝试过不是每次都创建集合并返回默认视图,而是为TypeB枚举项创建一次CollectionView,每次都根据Filter应用新的SelectedRow

    这种方法的问题是ComboBox的SelectedItem为null,当AvailableTypeB正在改变并且SelectedItem不再是它的一部分时。我试图改变绑定ModeIsSynchronizedWithCurrentItem,但没有运气。

  2. 我尝试的第二种方法是在ComboBox.Loaded事件上填充ComboBox.ItemsSource。这可以用几种方式实现,我试过的是

    - 有一个Loaded事件并在后面的代码中执行ComboBox.ItemsSource =

    - 使用Interactivity引用以获取命令而不是加载的事件。

    他们两人都“打破”MVVM模式。使用Interactivity程序集时,我必须将ComboBox控件传递给模型才能访问其数据源,这直接违反了MVVM

    我知道有第三种方法,即使用我尚未尝试的附加行为。

  3. 将可用TypeB值的集合作为我的MyObject类中的only-get属性。这是更清晰的解决方案,但它使我的MyObject类不那么通用。我的程序的某些部分用户可以更改上述规则不适用的TypeB值,这就是我想避免这种方法的原因。

  4. 注1:由于这是一篇很长的帖子,我试图将代码示例保持在最低限度。如果您认为某些细节遗失,请询问他们,我将编辑/更新 注2:我知道问题的某些部分可能是“基于意见的”,也许codeReview是一个更好的地方。

0 个答案:

没有答案