我正在尝试将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;
}
}
知道我缺少什么吗?
答案 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>