简体   繁体   English

XAML ItemsControl项未显示

[英]XAML ItemsControl items not showing

I'm trying to convert XAML WP8 code to WPF. 我正在尝试将XAML WP8代码转换为WPF。 The purpose is showing conversations in chat bubble style, which works op WP8. 目的是以聊天气泡样式显示对话,这在WP8上有效。

It consists of a Message object, which stores information about the message, a MessageCollection object which stores them as a ObservableCollection, and a ContentPresenter, which inherits ContentControl. 它由一个Message对象(用于存储有关消息的信息),一个MessageCollection对象(将其存储为ObservableCollection)和一个ContentPresenter(其继承ContentControl)组成。 In there two DataTemplates are defined which should be picked by the xaml code. 在其中定义了两个DataTemplates,它们应该由xaml代码选择。

I've been searching for days and trying everything, but whenever I start the project it just shows 'ChatBubble.Message' (which is a message object), so no text and no template is applied. 我一直在寻找几天并尝试所有方法,但是每当我启动该项目时,它只会显示“ ChatBubble.Message”(这是一个消息对象),因此没有文本且没有模板。 The layout itself works when tested without the itemscontrol binding. 在没有itemscontrol绑定的情况下进行测试时,布局本身可以工作。

I tried debugging by using Debug.Show in the ContentPresenter, which proved that it does get accessed by the ConversationView. 我尝试使用ContentPresenter中的Debug.Show进行调试,这证明ConversationView确实可以访问它。 It also showed that it does contain the test data I added, and differentiates between the two templates (MeTemplate and YouTemplate to place the bubble right or left). 它还显示它确实包含我添加的测试数据,并区分了两个模板(MeTemplate和YouTemplate分别将气泡放置在右侧或左侧)。

The ConversationView, which shows the bubbles in XAML: 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>

Here's the ContentPresenter: 这是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;
        }
    }

Any idea what I'm missing? 知道我缺少什么吗?

In WPF you would usually use a DataTemplateSelector to select the proper DataTemplate for each item: 在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;
    }
}

You would assign it to the ItemsControl's ItemTemplateSelector property like this: 您可以将其分配给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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM