XAML ItemsControl项目未显示

时间:2014-03-17 10:32:42

标签: c# wpf xaml

我正在尝试将XAML WP8代码转换为WPF。目的是显示聊天气泡样式的对话,它适用于WP8。

它由一个Message对象和一个ContentPresenter组成,Message对象存储有关消息的信息,MessageCollection对象将它们存储为ObservableCollection,ContentPresenter继承ContentControl。在那里定义了两个DataTemplates,应该由xaml代码选择。

我一直在寻找几天并尝试一切,但每当我启动项目时,它只显示'ChatBubble.Message'(这是一个消息对象),因此不会应用任何文本和模板。在没有itemscontrol绑定的情况下进行测试时,布局本身就可以工作。

我尝试在ContentPresenter中使用Debug.Show进行调试,这证明ConversationView可以访问它。它还显示它确实包含我添加的测试数据,并区分两个模板(MeTemplate和YouTemplate将气泡向右或向左放置)。

ConversationView,显示XAML中的气泡:

<Grid x:Name="LayoutRoot" Background="Black">
    <ItemsControl ItemsSource="{Binding}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <local:MessageContentPresenter Content="{Binding}">
                    <local:MessageContentPresenter.MeTemplate>
                        <DataTemplate>
                            <Grid Margin="30, 10, 5, 0"
                  local:GridUtils.RowDefinitions=",,"
                  Width="420">
                                <Rectangle Fill="White"
                         Grid.RowSpan="2"/>
                                <TextBlock Text="{Binding Path=Text}"
                         Style="{StaticResource TextBlockStyle}"/>
                                <TextBlock Text="{Binding Path=Timestamp, Converter={StaticResource StringFormatConverter}, ConverterParameter='ddd, HH:mm'}"
                         Style="{StaticResource TimestampStyle}"
                         Grid.Row="1"/>
                                <Path Data="m 0,0 l 16,0 l 0,16 l -16,-16"
                    Fill="White"
                    Margin="0,0,5,0"
                    HorizontalAlignment="Right"
                    Grid.Row="2"/>
                            </Grid>
                        </DataTemplate>
                    </local:MessageContentPresenter.MeTemplate>
                    <local:MessageContentPresenter.YouTemplate>
                        <DataTemplate>
                            <Grid Margin="5, 10, 30, 0"
                  local:GridUtils.RowDefinitions=",,"
                  Width="420">

                                <Path Data="m 0,0 l 0,16 l 16,0 l -16,-16"
                    Fill="White"
                    Margin="5,0,0,0"
                    HorizontalAlignment="Left"/>
                                <Rectangle Fill="White"
                         Grid.Row="1" Grid.RowSpan="2"/>
                                <TextBlock Text="{Binding Path=Text}"
                         Style="{StaticResource TextBlockStyle}"
                         Grid.Row="1"/>
                                <TextBlock Text="{Binding Path=Timestamp, Converter={StaticResource StringFormatConverter}, ConverterParameter='ddd, HH:mm'}"
                         Style="{StaticResource TimestampStyle}"
                         Grid.Row="2"/>
                            </Grid>
                        </DataTemplate>
                    </local:MessageContentPresenter.YouTemplate>
                </local:MessageContentPresenter>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>          
</Grid>

这是ContentPresenter:

public class MessageContentPresenter : ContentControl
{
    public DataTemplate MeTemplate { get; set; }

    public DataTemplate YouTemplate { get; set; }

    protected override void OnContentChanged(object oldContent, object newContent)
    {
        base.OnContentChanged(oldContent, newContent);

        Message message = newContent as Message;

        if (message.Side == MessageSide.Me)
        {
            ContentTemplate = MeTemplate;
        }
        else
        {
            ContentTemplate = YouTemplate;
        }
    }

知道我缺少什么吗?

1 个答案:

答案 0 :(得分:0)

在WPF中,您通常会使用DataTemplateSelector为每个项目选择合适的DataTemplate:

public class MessageTemplateSelector : DataTemplateSelector
{
    public DataTemplate MeTemplate { get; set; }
    public DataTemplate YouTemplate { get; set; }

    public override DataTemplate SelectTemplate(
        object item, DependencyObject container)
    {
        var message = item as Message;
        return message.Side == MessageSide.Me ? MeTemplate : YouTemplate;
    }
}

您可以将它分配给ItemsControl的ItemTemplateSelector属性,如下所示:

<Window.Resources>
    <DataTemplate x:Key="MeTemplate">
        ...
    </DataTemplate>
    <DataTemplate x:Key="YouTemplate">
        ...
    </DataTemplate>
</Window.Resources>
...
<ItemsControl ItemsSource="{Binding}">
    <ItemsControl.ItemTemplateSelector>
        <local:MessageTemplateSelector
            MeTemplate="{StaticResource MeTemplate}"
            YouTemplate="{StaticResource YouTemplate}"/>
    </ItemsControl.ItemTemplateSelector>
</ItemsControl>