CompositeCollection包含ICollectionView

时间:2016-01-07 10:21:45

标签: xaml tabs

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

所以标题标题'截图'的示例可能是:

tabA | tabB | tabC | config

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

tabA | config

config

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

我在添加配置页面项时遇到问题,因为我不知道在哪里添加它。我以为我可以将标签的ItemsSource设置为CompositeCollection,其中最后一项是配置页面对象。我未能实现这一点。

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

        <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}。这个“视图”来自我的ViewModel,是一个ICollectionView。

理想情况下,我可以做一些神奇的事情:

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

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

作为参考,{Binding View}中的每个项目都是一个包含Value属性的对象,value属性包含一个对象,在本例中包含siteDisplayName和siteComment。

作为参考,选项卡的DataContext定义了包含它的dockpanel,如下所示。

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

作为参考,Configurator是我的viewmodel,并在xaml中实例化为:

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

所以,实际的问题是: 如何在选项卡控件的末尾添加“配置页”?优选地,通过使用上述希望的方法在CompositeCollection上添加额外的配置页面对象;但如果这是不可能的[1]我愿意接受建议。

[1]我认为它不起作用,因为{Binding View}是一个ICollectionView,而CompositeCollection需要一个“集合”,并且不接受“视图”

谢谢。 彼得。

1 个答案:

答案 0 :(得分:0)

我决定通过代码来实现它。这意味着我无法使用设计时数据来预览我的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 enter image description here

我现在只需要填充我的设置标签项,我就完成了。 作为参考,xaml设计器没有任何预览数据 - 除非我更改xaml以便预览加载(然后打破实际执行)

让它在跑步和预览时都能正常工作会很不错,但我还没有想出如何做到这一点,而且它不是当前的优先事项。