包含 ICollectionView 的 CompositeCollection

CompositeCollection containing an ICollectionView

我正在尝试实现一个选项卡控件,其中每个项目都来自我的视图模型的 ICollectionView。每个标签页,对于 ICollectionView 中的项目都是相同的。但是,我希望有一个额外的配置选项标签页。

因此,示例选项卡 header 'screenshot' 可能是:

tabA | tabB | tabC | config

在另一个实例中,它可能是

tabA | config

config

我可以使用 ItemTemplateSelectors 为每个项目定义 header,并使用 ContentTemplateSelectors 定义内容。所以那一点应该没问题。

我在添加配置页面项目时遇到问题,因为我不知道在哪里添加它。我想我可以将选项卡的 ItemsSource 设置为 CompositeCollection,其中最后一项是配置页面 object。我没能做到这一点。

在下面的示例中,我可以查看选项卡 headers 根据我设置的设计器样本数据正确填充 - 我还没有添加配置页面。

        <controls:MetroTabControl ItemsSource="{Binding View}">
            <controls:MetroTabControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Value.siteDisplayName}" />
                </DataTemplate>
            </controls:MetroTabControl.ItemTemplate>
            <controls:MetroTabControl.ContentTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Value.siteComment}"/>
                </DataTemplate>
            </controls:MetroTabControl.ContentTemplate>
        </controls:MetroTabControl>

如您所见,我已将 ItemsSource 设置为 {Binding View}。这个 "View" 来自我的 ViewModel,是一个 ICollectionView。

理想情况下,我可以像这样施展魔法:

        <controls:MetroTabControl>
            <controls:MetroTabControl.ItemsSource>
                <CompositeCollection>
                    <CollectionContainer Collection="{Binding View}"/>
                    <SomeConfigPageObject/>
                </CompositeCollection>
            </controls:MetroTabControl.ItemsSource>
              ...snip...
        </controls:MetroTabControl>

但问题是,当我执行上述操作时,控件的设计器预览就像 ItemsSource 中没有项目一样。

作为参考,{绑定视图}中的每个项目都是一个 object,其中包含一个值 属性,值 属性 包含一个 object,其中包含,在此示例中,siteDisplayName 和 siteComment.

作为参考,选项卡的 DataContext 在包含它的停靠面板中定义,如下所示。

<DockPanel DataContext="{Binding Source={StaticResource Configurator}}"
            d:DataContext="{d:DesignInstance cfuid:ConfigSiteVMSampleData, IsDesignTimeCreatable=true}"
            LastChildFill="True">

供参考,配置器是我的视图模型,在 xaml 中实例化为:

<UserControl.Resources>
    <ResourceDictionary>
        ...snip...
        <cfvmc:ConfigSiteVM x:Key="Configurator" />
        ...snip...

所以,实际的问题是: 如何在选项卡控件的末尾添加 "config page"?最好通过使用 above-hoped 方法在 CompositeCollection 上添加额外的 config-page object;但是,如果这不可能 [1],我愿意接受建议。

[1] 我认为它不起作用,因为 {Binding View} 是一个 ICollectionView 而 CompositeCollection 需要一个 "collection" 并且不接受 "view"

谢谢。 彼得.

我决定通过隐藏代码来实现。这意味着我确实无法使用 design-time 数据来预览我的 UI;但它在 运行 时间有效。

所以,在 xaml 我有。

        <controls:MetroTabControl Grid.Column="0" Grid.ColumnSpan="2"
                Grid.Row="0" Grid.RowSpan="2"
                ItemsSource="{Binding ElementName=ucMe, Path=TabSitesCollection}">

其中 ucMe 是 UserControl,TabSitesCollection 是

    protected CollectionViewSource m_TabSitesCollectionViewSource;
    protected CompositeCollection m_TabSitesComposites;
    public ICollectionView TabSitesCollection
    {
        get { return m_TabSitesCollectionViewSource.View; }
    }

在构造函数中初始化如下

    public ConfigSiteView()
    {
        m_TabSitesComposites = new CompositeCollection();
        m_TabSitesCollectionViewSource = new CollectionViewSource();
        m_TabSitesCollectionViewSource.Source = m_TabSitesComposites;

        InitializeComponent();
    }

然后,在 Loaded 事件上我可以做

        m_TabSitesComposites.Add(new CollectionContainer() { Collection = GetModel.View });
        m_TabSitesComposites.Add(new TabItem() { Header = "hi" });
        m_TabSitesComposites.Add(new TabItem() { Header = "ho" });

这几乎是我想要的 UI

我现在只需要修饰我的设置选项卡项就可以了。 作为参考,xaml 设计器没有任何预览数据 - 除非我更改 xaml 以便加载预览(然后中断实际执行)

如果它在 运行 期间和预览时都能正常工作就好了,但我还没有想出如何做到这一点,而且这不是当前的优先事项。