在我的应用程序中,我使用的是C#,WPF,我正在遵循MVVM模式。
我想要实现的目标如下:
我有一个DataGrid
,ItemSource
在我的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模式。有什么想法或建议吗?
将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不再是它的一部分时。我试图改变绑定Mode
和IsSynchronizedWithCurrentItem
,但没有运气。
我尝试的第二种方法是在ComboBox.Loaded事件上填充ComboBox.ItemsSource。这可以用几种方式实现,我试过的是
- 有一个Loaded事件并在后面的代码中执行ComboBox.ItemsSource =
- 使用Interactivity引用以获取命令而不是加载的事件。
他们两人都“打破”MVVM模式。使用Interactivity程序集时,我必须将ComboBox
控件传递给模型才能访问其数据源,这直接违反了MVVM
我知道有第三种方法,即使用我尚未尝试的附加行为。
将可用TypeB值的集合作为我的MyObject
类中的only-get属性。这是更清晰的解决方案,但它使我的MyObject
类不那么通用。我的程序的某些部分用户可以更改上述规则不适用的TypeB
值,这就是我想避免这种方法的原因。
注1:由于这是一篇很长的帖子,我试图将代码示例保持在最低限度。如果您认为某些细节遗失,请询问他们,我将编辑/更新 注2:我知道问题的某些部分可能是“基于意见的”,也许codeReview是一个更好的地方。