我正在使用MVVM模式编写应用程序.我通过将我的视图的DataContext属性设置为我的ViewModel的实例来向我的视图提供数据.一般来说,我只是从那里使用Binding并继续我的方式.
最近,我试图在我的ViewModel提供的"选择项目"的集合之外实现一个带有"额外"元素的ComboBox.
<ComboBox>
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem IsEnabled="False">Select Item</ComboBoxItem>
<CollectionContainer Collection="{Binding MyItemsCollection}" />
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
Run Code Online (Sandbox Code Playgroud)
问题是,CompositeCollection不是Freezable:Freezable Objects Overview.这会导致仅显示静态ComboBoxItem,而不会导致我的绑定表达式产生任何结果.
我对这个问题的第一反应是,只是实现自己CompositeCollection的版本是可冻结.但是,这引出了以下问题:
为什么CompositeCollection首先不是Freezable?
我担心的是,通常这些决定是出于某种原因而做出的,我不觉得我对Freezable的了解不足以说明为什么他们没有从中继承.我知道我可以实现这个系列,但我担心如果我这样做会有一个可衡量的性能差异.
任何帮助,将不胜感激.谢谢!
另外:请注意,我意识到我可以插入Null或其他一些特殊值,并提供模板或valueconverter来做我想要的.这不是我感兴趣的问题......只是上面的粗体问题.
更新:
经过ArsenMkrt的评论进行了一些进一步的研究后,我发现我认为这实际上是一种疏忽.证据如下:
FreezableCollection<T>.我没有生成CollectionViews,这使得它不能直接满足我的需求.我目前解决这个问题的计划是创建一个具有CompositeCollection和属性的新集合FreezableCollection<T>.我不知道它是否还能正常工作,但我正在考虑这样的事情:
public class BindableCompositeCollection : FreezableCollection<object>, ICollectionViewFactory
Run Code Online (Sandbox Code Playgroud)
如果有人有更好的选择,我想听听!
我的 WPF 项目中有一些简单的层次结构。
我有基类,称为产品。然后我从这个基类继承了两个类。然后我从他们两个继承了更多的类。
所以我有 Product 类,然后是 Book 和 Disk 类,它们继承自 Product 类,以及 RecipeBook 类、ProgramingBook 类和 AdventureBook 类,它们继承自 Book 类。
然后我创建集合并在那里添加一些书,比如 collection.Add(new RecipeBook() {bla bla bla});
最后我收集了不同的类。
所以我需要的只是通过 WPF TreeView 显示所有这些东西。
它会是这样的:
Product
Book
RecipeBook
Book#1
Book#2
ProgramingBook
Book#1
....
Disk
Disk#1
Disk#2
.....
Run Code Online (Sandbox Code Playgroud)
那我该怎么做呢?
<TreeView x:Name="treeView" Height="224" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="337" >
<TreeViewItem Header="Products" >
<TreeViewItem Header="Books">
<TreeViewItem Header="Recipe"></TreeViewItem>
<TreeViewItem Header="Programing"></TreeViewItem>
<TreeViewItem Header="Adventure"></TreeViewItem>
</TreeViewItem>
<TreeViewItem Header="CDs">
</TreeViewItem>
</TreeViewItem>
</TreeView>
Run Code Online (Sandbox Code Playgroud)