标签: compositecollection

为什么CompositeCollection不能Freezable?

我正在使用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的评论进行了一些进一步的研究后,我发现我认为这实际上是一种疏忽.证据如下:

  1. 有一个可以冻结的集合FreezableCollection<T>.我没有生成CollectionViews,这使得它不能直接满足我的需求.
  2. MSFT的Sam Bent在上面的链接中说了很多.我还找不到他的联系方式,但如果有机会,我打算和他讨论这个问题.

我目前解决这个问题的计划是创建一个具有CompositeCollection和属性的新集合FreezableCollection<T>.我不知道它是否还能正常工作,但我正在考虑这样的事情:

public class BindableCompositeCollection : FreezableCollection<object>, ICollectionViewFactory
Run Code Online (Sandbox Code Playgroud)

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

wpf freezable compositecollection

22
推荐指数
1
解决办法
4094
查看次数

CompositeCollection + CollectionContainer:将CollectionContainer.Collection绑定到ViewModel的属性,该属性用作DataTemplates DataType

我没有得到正确的绑定语法访问CatsDogs属性MyViewModelDateTemplate定义了CompositeCollection它的资源范围内.

public class MyViewModel
{
    public ObservableCollection<Cat> Cats { get; private set; }
    public ObservableCollection<Dog> Dogs { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
<DataTemplate DataType={x:Type local:MyViewModel}">
  <DataTemplate.Resources>
    <CompositeCollection x:Key="MyColl">
      <!-- How can I reference the Cats and Dogs properties of MyViewModel? -->
      <CollectionContainer Collection="{Binding Dogs, ????}">
      <CollectionContainer Collection="{Binding Cats, ????}">
    </CompositeCollection>
  </DataTemplate.Resources>
  <ListBox ItemsSource="{StaticResource MyColl}">
    <!-- ... -->
  </ListBox>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

我要为????插入什么?绑定DogsCats集合到CollectionContainers?

c# data-binding wpf datatemplate compositecollection

14
推荐指数
1
解决办法
7490
查看次数

CompositeCollection/CollectionViewSource混淆

我对使用这些类型时数据绑定的工作方式感到有些困惑.

我读过你不能做以下事情

public partial class Window1 : Window
    {
        public ObservableCollection<string> Items { get; private set; }

        public Window1()
        {
            Items = new ObservableCollection<string>() { "A", "B", "C" };
            DataContext = this;
            InitializeComponent();
        }
    }

<Window x:Class="WpfApplication25.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <ComboBox>
        <ComboBox.ItemsSource>
            <CompositeCollection>
                <CollectionContainer Collection="{Binding Items}"/>
            </CompositeCollection>
        </ComboBox.ItemsSource>
    </ComboBox>
</Window>
Run Code Online (Sandbox Code Playgroud)

因为CompositeCollection没有datacontext的概念,因此使用绑定的任何内容都必须设置Source属性.如下:

<Window x:Class="WpfApplication25.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Window.Resources>
        <CollectionViewSource x:Key="list" Source="{Binding Items}"/>
    </Window.Resources>

    <ComboBox Name="k">
        <ComboBox.ItemsSource>
            <CompositeCollection>
               <CollectionContainer Collection="{Binding Source={StaticResource list}}"/>
            </CompositeCollection>
        </ComboBox.ItemsSource>
    </ComboBox>
</Window>
Run Code Online (Sandbox Code Playgroud)

但那是怎么回事?它将源设置为某些东西,但是在某些情况下,CollectionViewSource使用datacontext(因为它没有明确设置源).

因为"list"是在Window的资源中声明的,这是否意味着它获取了Windows DataContext?在这种情况下,为什么以下也不起作用?

<Window x:Class="WpfApplication25.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Window.Resources> …
Run Code Online (Sandbox Code Playgroud)

wpf datacontext compositecollection collectionviewsource staticresource

7
推荐指数
1
解决办法
2443
查看次数

如何使用CollectionView功能处理CompositeCollection?

当CompositeCollection的当前位置发生变化时,有没有办法得到通知?

我需要通过CollectionView监控CompositeCollection,任何想法都很受欢迎.

wpf observablecollection compositecollection collectionviewsource

6
推荐指数
1
解决办法
4935
查看次数

迭代 CompositeCollection 的项目

考虑代码:

\n\n
ObservableCollection<string> cities = new ObservableCollection<string>();\nObservableCollection<string> states = new ObservableCollection<string>();\n\nListBox list;\n\ncities.Add("Frederick");\ncities.Add("Germantown");\ncities.Add("Arlington");\ncities.Add("Burbank");\ncities.Add("Newton");\ncities.Add("Watertown");\ncities.Add("Pasadena");\n\nstates.Add("Maryland");\nstates.Add("Virginia");\nstates.Add("California");\nstates.Add("Nevada");\nstates.Add("Ohio");\n\nCompositeCollection cmpc = new CompositeCollection();\nCollectionContainer cc1 = new CollectionContainer();\nCollectionContainer cc2 = new CollectionContainer();\n\ncc1.Collection = cities;\ncc2.Collection = states;\n\ncmpc.Add(cc1);\ncmpc.Add(cc2);\n\nlist.ItemsSource = cmpc;\n\nforeach(var itm in cmpc)\n{\n    // itm is CollectionContainer and there are only two itm\xe2\x80\x99s\n    // I need the strings\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

虽然列表在 GUI 上显示了正确的数据

\n\n

我需要这些数据(不引用列表框)但我没有得到它

\n

.net compositecollection

5
推荐指数
1
解决办法
1545
查看次数

如何使用数据库绑定向WPF中的组合框添加选项"All"

ComboBox在WPF中有以下内容.我知道我可以ALL使用CompositeCollection 添加选项,但我不知道如何.如果有人帮我解决一个简短的教程,那将会很棒.

<ComboBox SelectionChanged="ComboBoxOperatingPoints_SelectionChanged" 
          x:Name="ComboBoxOperatingPoints" 
          DropDownOpened="ComboBoxOperatingPoints_DropDownOpened_1"
          FontSize="30" 
          HorizontalAlignment="Right" 
          Margin="40,40,0,0" 
          VerticalAlignment="Top" 
          Width="200" 
          Height="50"
          IsSynchronizedWithCurrentItem="True"
          ItemsSource="{Binding OperatingPoints}"
          DisplayMemberPath="name"
          SelectedValue="{Binding OperatingPointID,UpdateSourceTrigger=PropertyChanged,TargetNullValue=''}"
          SelectedValuePath="operating_point_id">
</ComboBox>
Run Code Online (Sandbox Code Playgroud)

.net wpf combobox compositecollection

5
推荐指数
1
解决办法
3319
查看次数

CompositeCollection的源代码:为什么我不能绑定另一个控件的数据上下文但必须使用CollectionViewSource?

我最近提出的另一个问题中,我被告知使用a CompositeCollection来访问各种来源ListBox.

该示例使用a XmlDataProvider来提供一些虚拟数据.但是,我有一个包含数据的视图模型.

我花了一些时间来绑定ListBox视图模型的数据.最终我明白了,但现在我想明白为什么我以前的方法不起作用.

成功的关键是CollectionViewSource.我最初的尝试是:

<CollectionContainer Collection="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Movies}"/>
<CollectionContainer Collection="{Binding ElementName=Window, Path=DataContext.Movies}"/>
Run Code Online (Sandbox Code Playgroud)

我的想法是找到具有相应DataContext的Window,并绑定数据.你可以通过FindAncestor或通过ElementName,所以我尝试了两个.这对我来说似乎很合乎逻辑,但显然我错了.我运行应用程序时没有看到任何内容.
我还尝试绑定另一个具有数据上下文的控件; 例如StackPanel.

那么,为什么我不用1FindAncestorElementName1获取数据,但必须CollectionViewSource明确提供?


这是正在运行的代码.

<StackPanel DockPanel.Dock="Top">
    <ListBox ItemTemplateSelector="{StaticResource CustomDataTemplateSelector}">
        <ListBox.Resources>
            <CollectionViewSource x:Key="ViewSource" Source="{Binding Movies}"/>
        </ListBox.Resources>
        <ListBox.ItemsSource>
            <CompositeCollection>
                <CollectionContainer Collection="{Binding Source={StaticResource ViewSource}}"/>
                <CollectionContainer Collection="{Binding Source={StaticResource MyButtonsData}}"/>
            </CompositeCollection>
        </ListBox.ItemsSource>
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel IsItemsHost="True"
                   Width="{Binding (FrameworkElement.ActualWidth),
                               RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

1 …

data-binding wpf compositecollection collectionviewsource

5
推荐指数
1
解决办法
2589
查看次数

WPF CompositeCollection 按每个集合视图分组

我已经设置了一个CompositeCollection包含两个或多个集合的如下(简化):

<Grid.Resources>
    <CollectionViewSource x:Key="CollectionA" Source="{Binding CollectionA}" />
    <CollectionViewSource x:Key="CollectionB" Source="{Binding CollectionB}" />
    <CompositeCollection x:Key="FullCollection">
        <CollectionContainer Collection="{Binding Source={StaticResource CollectionA}}" />
        <CollectionContainer Collection="{Binding Source={StaticResource CollectionB}}" />
    </CompositeCollection>
</Grid.Resources>
Run Code Online (Sandbox Code Playgroud)

...

<ListView ItemsSource="{StaticResource FullCollection}">
    <ListView.View>
        <GridView>
Run Code Online (Sandbox Code Playgroud)

然后一些列显示在GridView. 但是,我似乎无法添加GroupDescriptionsCompositeCollection,只有单个CollectionViewSource元素。

我想要做的是按集合本身分组,这样ListView就有一个标题,然后是第一个集合的内容,另一个标题,然后是第二个集合的内容,等等。

我是否在尝试以这种方式对这些进行分组的错误树?

c# wpf compositecollection

5
推荐指数
1
解决办法
288
查看次数