【发布时间】:2014-03-17 20:01:43
【问题描述】:
我正在尝试将 XAML WP8 代码转换为 WPF。目的是以聊天气泡样式显示对话,适用于 WP8。
它由一个存储消息信息的 Message 对象、一个将它们存储为 ObservableCollection 的 MessageCollection 对象和一个继承 ContentControl 的 ContentPresenter 组成。在那里定义了两个 DataTemplate,应该由 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;
}
}
知道我错过了什么吗?
【问题讨论】:
-
只是想澄清一下。你在哪里看到
ChatBubble.Message?它是在 datatemplate 内的文本块中,还是直接在 itemscontrol 内(意思是 itemtemplate/datatemplate 没有被使用)? -
当我删除
<ItemsControl ItemsSource="{Binding}">标签之间的所有内容时,它仍然显示ChatBubble.Message,所以我从那里假设。 -
作为我之前声明的补充:它确实循环通过 itemtemplate/datatemplate,因为 ContentPresenter 中的
Debug.Print表明它已被访问。 -
如果您在 datatemplate 中硬编码文本块的文本而不是使用绑定,是显示硬编码文本还是仍然
ChatBubble.Message? -
还是
ChatBubble.Message