gpt4 book ai didi

wpf - 为什么 CompositeCollection 不可 Freezable?

转载 作者:行者123 更新时间:2023-12-02 08:44:30 31 4
gpt4 key购买 nike

我正在使用 MVVM 模式编写一个应用程序。我通过将 View 的 DataContext 属性设置为 ViewModel 的实例来向 View 提供数据。一般来说,我只是从那里使用 Binding 并继续我的方式。

最近,我尝试实现一个 ComboBox,其中包含一个超出 ViewModel 提供的“选择项”集合之外的“额外”元素。

<ComboBox>    
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem IsEnabled="False">Select Item</ComboBoxItem>
<CollectionContainer Collection="{Binding MyItemsCollection}" />
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>

问题是,CompositeCollection 不是 Freezable:Freezable Objects Overview 。这会导致仅出现静态 ComboBoxItem,而不会出现绑定(bind)表达式的任何结果。

我对这个问题的最初 react 是实现我自己的 Freezable 版本的 CompositeCollection。但这引出了以下问题:

为什么 CompositeCollection 不是 Freezable?

我担心的是,通常这些决定都是有原因的,而且我觉得我对 Freezable 的了解不够,无法说明为什么它们不继承它。我知道我可以实现这个集合,但我担心如果我这样做的话,性能会出现明显的差异。

如有任何帮助,我们将不胜感激。谢谢!

另外:请注意,我意识到我可以插入 Null 或其他一些特殊值,并提供模板或值转换器来执行我想要的操作。这不是我感兴趣的问题...只是上面粗体的问题。

更新:

经过 ArsenMkrt 的评论进行了一些进一步的研究,我相信这实际上是一个疏忽。证据是这样的:

  1. 有一个可卡住的集合,名为 FreezableCollection<T> 。它不会生成 CollectionViews,这使得它不适合我的直接需求。
  2. MSFT 的 Sam Bent 在上面的链接中也说了同样的话。我还找不到他的联系信息,但如果有机会,我计划与他讨论这个问题。

我当前解决此问题的计划是创建一个具有 CompositeCollection 和 FreezableCollection<T> 属性的新集合。 。我不知道它是否会起作用,但我正在考虑这样的事情:

public class BindableCompositeCollection : FreezableCollection<object>, ICollectionViewFactory

如果有人有更好的选择,我很想听听!

最佳答案

我今晚刚刚尝试过:

public class State
{
public string Code { get; set; }
public string Name { get; set; }
}

public class MyWindowViewModel
{
ObservableCollection<State> _states = new ObservableCollection<State>
{
new State { Code = "FL", Name = "Florida" },
new State { Code = "CA", Name = "California" },
};

public ObservableCollection<State> States
{
get
{
return _states;
}
}
}
<Window x:Class="WpfApplication1.MyWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:app="clr-namespace:WpfApplication1"
Title="Window1"
Height="300"
Width="300">

<Window.Resources>
<app:ServiceLocator x:Key="Locator" />
</Window.Resources>

<StackPanel>
<ComboBox x:Name="TestCombo" SelectedIndex="0" DisplayMemberPath="Name" SelectedValuePath="Code">
<ComboBox.ItemsSource>
<CompositeCollection>
<app:State Code="" Name="Select a state..." />
<app:State Code="TX" Name="Texas" />
<CollectionContainer Collection="{Binding Source={StaticResource Locator}, Path=MyWindowViewModel.States}" />
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
</StackPanel>
</Window>

这里的关键是创建服务定位器的实例作为静态资源,然后通过它来访问 View 模型。服务定位器可以使用 Unity 或任何您想要的 DI 连接到 ViewModel 的实例。

编辑:

实际上,在我的 silverlight 应用程序中,我在 App.xaml 中创建服务定位器作为静态资源,然后将我的其他 UserControls/Windows/Pages DataContext 绑定(bind)到服务定位器的 ViewModel 属性。即使服务定位器是在 App.xaml 的资源中实例化的,它对于组合框仍然应该以相同的方式工作。我希望有一个我可以使用的 CompositeCollection 的 silverlight 版本。这对于我正在开发的应用程序非常有用。 :(

关于wpf - 为什么 CompositeCollection 不可 Freezable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1189052/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com