Windows 10 UWP应用程序中的ItemsControl和ItemTemplateSelector

时间:2016-01-21 06:53:30

标签: c# xaml win-universal-app uwp

我很久以前做过一些WPF编程,但我只是回到xaml与UWP,但我认为这应该有效,无法弄清楚原因。基本上我想使用ItemsControl(因为我只想列出一些数据,我不想选择)而不是ListView控件。这是我的资源:

<Page.Resources>
    <DataTemplate x:Key="SentMessageDataTemplate">
        <TextBlock Text="Sent" />
    </DataTemplate>
    <DataTemplate x:Key="ReceivedMessageDataTemplate">
        <TextBlock Text="Recieved" />
    </DataTemplate>
    <services:MessageDataTemplateSelector x:Key="MessageDataTemplateSelector" ReceivedTemplate="{StaticResource ReceivedMessageDataTemplate}" SentTemplate="{StaticResource SentMessageDataTemplate}"></services:MessageDataTemplateSelector>
</Page.Resources>

这是我的ItemsControl:

<ItemsControl ItemsSource="{Binding Messages}" ItemTemplateSelector="{StaticResource MessageDataTemplateSelector}" />

这是我的DataTemplateSelector:

public class MessageDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate SentTemplate
    {
        get;
        set;
    }

    public DataTemplate ReceivedTemplate
    {
        get;
        set;
    }

    protected override DataTemplate SelectTemplateCore(object item)
    {
        var message = item as MessageViewModel;
        if (message == null)
        {
            return this.SentTemplate;
        }

        return message.Sent ? this.SentTemplate : this.ReceivedTemplate;
    }
}

不是显示我的任何模板,而是显示我的ViewModel类型名称(基本上是ToString)。

但是,如果我将它从ItemsControl切换到ListView,它可以正常工作。

有什么建议吗?

4 个答案:

答案 0 :(得分:11)

改为使用此覆盖:

protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)

这是被调用的那个,而不是没有第二个参数的那个。

答案 1 :(得分:5)

有趣 - ListView和GridView都调用模板选择器; plain ItemsControl或ListBox没有。

在模板选择器中覆盖其他 SelectTemplateCore方法有助于,例如:

protected override DataTemplate SelectTemplateCore(object item)
{
    var message = item as MessageViewModel;
    if (message == null)
    {
        return SentTemplate;
    }

    return message.Sent ? SentTemplate : ReceivedTemplate;
}

protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
    return SelectTemplateCore(item);
}

在所有情况下都会调用后一种方法;第一个不是ItemsControl个项目。 This page提供了各种解释:

  

如果您的ItemsControl.ItemsPanelItemsStackPanelItemsWrapGrid,请为SelectTemplateCore(Object)方法提供覆盖。如果ItemsPanel是其他面板,例如VirtualizingStackPanelWrapGrid,请为SelectTemplateCore(Object, DependencyObject)方法提供覆盖。

答案 2 :(得分:0)

也许你应该使用<TextBlock Text="{Binding Sent}" /> 你不要在你的模板中绑定任何东西。

答案 3 :(得分:0)

以下是文档说的内容:

<强>说明

如果ItemsControl.ItemsPanel是ItemsStackPanel或ItemsWrapGrid,请为SelectTemplateCore(Object)方法提供覆盖。如果ItemsPanel是不同的面板,例如VirtualizingStackPanel或WrapGrid,则为SelectTemplateCore(Object,DependencyObject)方法提供覆盖。