2016-01-06 77 views
0

有些人可以确定为什么以下不能正常工作,我试图实现一个聊天消息窗口,其中每个消息将呈现不同的样式,取决于MessageDirection。为此,我现在用的这势必给Messages财产ItemsControl基于内容的不同模板

在ChatWindow类ItemsControl我有以下

public static readonly DependencyProperty MessagesProperty = DependencyProperty.Register(
     "Messages", 
     typeof(ObservableCollection<Message>), 
     typeof(ChatWindow), 
     new PropertyMetadata(null)); 

public ObservableCollection<Message> Messages 
{ 
    get 
    { 
     return (ObservableCollection<Message>)this.GetValue(MessagesProperty); 
    } 

    set 
    { 
     this.SetValue(MessagesProperty, value); 
    } 
} 

,我有以下在ResourceDictionary中

<ScrollViewer x:Name="srcMessages" Margin="0,0,0,0" VerticalScrollBarVisibility="Visible"> 
    <StackPanel> 
     <ItemsControl ItemsSource="{Binding Path=Messages, RelativeSource={RelativeSource AncestorType={x:Type chat:ChatWindow}}}" x:Name="Messages"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <chat:MessageContentPresenter Content="{Binding}"> 
         <chat:MessageContentPresenter.InboundTemplate> 
          <DataTemplate> 
           <Grid> 
            <Grid.RowDefinitions> 
             <RowDefinition Height="Auto" /> 
             <RowDefinition Height="Auto" /> 
            </Grid.RowDefinitions> 
            <Grid Grid.Row="0"> 
             <Grid.ColumnDefinitions> 
              <ColumnDefinition Width="94" /> 
              <ColumnDefinition Width="Auto" /> 
              <ColumnDefinition Width="*" /> 
             </Grid.ColumnDefinitions> 
             <StackPanel Grid.Column="1" Orientation="Horizontal"> 
              <TextBlock Text="Username One" FontSize="10" Foreground="#adadad"></TextBlock> 
              <TextBlock Text=" - " FontSize="10" Foreground="#adadad"></TextBlock> 
              <TextBlock Text="11:45 AM" FontSize="10" Foreground="#adadad"></TextBlock> 
             </StackPanel> 
            </Grid> 

            <Grid Grid.Row="1"> 
             <Grid.ColumnDefinitions> 
              <ColumnDefinition Width="18" /> 
              <ColumnDefinition Width="65" /> 
              <ColumnDefinition Width="5" /> 
              <ColumnDefinition Width="6" /> 
              <ColumnDefinition Width="230" /> 
              <ColumnDefinition Width="*" /> 
             </Grid.ColumnDefinitions> 
             <Image Grid.Column="1" Height="60" Width="60" Source="pack://siteoforigin:,,,/Resources/noavatar.png" StretchDirection="Both" Stretch="Fill"> 
              <Image.Clip> 
               <EllipseGeometry Center="30,30" RadiusX="30" RadiusY="30" /> 
              </Image.Clip> 
             </Image> 
             <Polygon Grid.Column="3" Points="0,0 -4,3 0,6 0,0" StrokeThickness="2" HorizontalAlignment="Right" VerticalAlignment="Center" Fill="#d8d7dc" Stroke="#d8d7dc"></Polygon> 
             <Border Grid.Column="4" BorderBrush="#d8d7dc" BorderThickness="1" Background="#d8d7dc" Padding="5"> 
              <TextBlock TextWrapping="Wrap" Text="This is a message in a chat window..." VerticalAlignment="Top" FontSize="12" Foreground="#000000"></TextBlock> 
             </Border> 
            </Grid> 
           </Grid> 
          </DataTemplate> 
         </chat:MessageContentPresenter.InboundTemplate> 
         <chat:MessageContentPresenter.OutboundTemplate> 
          <DataTemplate> 
           <Grid> 
            <Grid.RowDefinitions> 
             <RowDefinition Height="Auto" /> 
             <RowDefinition Height="Auto" /> 
            </Grid.RowDefinitions> 
            <Grid Grid.Row="0"> 
             <Grid.ColumnDefinitions> 
              <ColumnDefinition Width="*" /> 
              <ColumnDefinition Width="Auto" /> 
              <ColumnDefinition Width="94" /> 
             </Grid.ColumnDefinitions> 
             <StackPanel Grid.Column="1" HorizontalAlignment="Right" Orientation="Horizontal"> 
              <TextBlock Text="Username One" FontSize="10" Foreground="#adadad"></TextBlock> 
              <TextBlock Text=" - " FontSize="10" Foreground="#adadad"></TextBlock> 
              <TextBlock Text="11:45 AM" FontSize="10" Foreground="#adadad"></TextBlock> 
             </StackPanel> 
            </Grid> 

            <Grid Grid.Row="1"> 
             <Grid.ColumnDefinitions> 
              <ColumnDefinition Width="*" /> 
              <ColumnDefinition Width="230" /> 
              <ColumnDefinition Width="6" /> 
              <ColumnDefinition Width="5" /> 
              <ColumnDefinition Width="65" /> 
              <ColumnDefinition Width="18" /> 
             </Grid.ColumnDefinitions> 
             <Image Grid.Column="4" Height="60" Width="60" Source="pack://siteoforigin:,,,/Resources/noavatar.png" StretchDirection="Both" Stretch="Fill"> 
              <Image.Clip> 
               <EllipseGeometry Center="30,30" RadiusX="30" RadiusY="30" /> 
              </Image.Clip> 
             </Image> 
             <Polygon Grid.Column="2" Points="0,0 4,3 0,6 0,0" StrokeThickness="2" HorizontalAlignment="Right" VerticalAlignment="Center" Fill="#4fcd00" Stroke="#4fcd00"></Polygon> 
             <Border Grid.Column="1" BorderBrush="#4fcd00" BorderThickness="1" Background="#4fcd00" Padding="5"> 
              <TextBlock TextWrapping="Wrap" Text="This is a message in a chat window..." VerticalAlignment="Top" FontSize="12" Foreground="#000000"></TextBlock> 
             </Border> 
            </Grid> 
           </Grid> 
          </DataTemplate> 
         </chat:MessageContentPresenter.OutboundTemplate> 
        </chat:MessageContentPresenter> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </StackPanel> 
</ScrollViewer> 

和定义的MessageContentPresenter如下

public class MessageContentPresenter : ContentControl 
{ 
    #region Public Properties 

    public DataTemplate InboundTemplate { get; set; } 

    public DataTemplate OutboundTemplate { get; set; } 

    #endregion 

    #region Methods 

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

     var message = newContent as Message; 
     if (message.Direction == MessageDirection.Inbound) 
     { 
      this.ContentTemplate = this.InboundTemplate; 
     } 
     else 
     { 
      this.ContentTemplate = this.OutboundTemplate; 
     } 
    } 

    #endregion 
} 

当我运行此代码时,所有工作都正常,Messages集合中的每个项目都会执行一次OnContentChanged方法。问题是InboundTemplateOutboundTemplate都是null

我真的不明白问题是什么,为什么这两个模板都是null,任何帮助不胜感激。

+0

也许'Content'属性之前入站和出站的模板设置。我认为使用自定义['DataTemplateSelector']会更好(https://msdn.microsoft.com/en-us/library/system.windows.controls.datatemplateselector(v = vs.110).aspx) – dkozl

+0

你有一个基于上述 –

+0

的示例实现我目前无法访问PC,但MSDN网站上面的链接应该有一个 – dkozl

回答

0

的确,您可以使用DataTemplateSelector。

但另一种选择是使用的DataTemplate + ContentControl中和风格:

首先,放弃你的MessageContentPresenter类,因为我们并不需要它。因此,您需要从您的XAML中删除您的ItemsControl.ItemTemplate。其次,将DataTemplate + ContentControl和Style添加到您的Window.Resources中。

试试这个给你一些铅:

<DataTemplate DataType="{x:Type local:Message}"> 
     <ContentControl Content="{Binding Direction}"> 
      <ContentControl.Style> 
       <Style TargetType="{x:Type ContentControl}"> 
        <Style.Triggers> 
         <DataTrigger Binding="{Binding Direction}" Value="{x:Static local:MessageDirection.Inbound}"> 
          <Setter Property="ContentTemplate"> 
           <Setter.Value> 
            <DataTemplate> 
             <Button Background="Green">Inbound</Button> 
            </DataTemplate> 
           </Setter.Value> 
          </Setter> 
         </DataTrigger> 
         <DataTrigger Binding="{Binding Direction}" Value="{x:Static local:MessageDirection.Outbound}"> 
          <Setter Property="ContentTemplate"> 
           <Setter.Value> 
            <DataTemplate> 
             <Button Background="Red">Outbound</Button> 
            </DataTemplate> 
           </Setter.Value> 
          </Setter> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </ContentControl.Style> 
     </ContentControl> 
    </DataTemplate> 
+0

这是最初看到的,但我的设计类似于iOS的文本对话其中入站和出站模板分别左对齐和右对齐,而不仅仅是不同的颜色,但布局也不同,这就是我采取的方法 –

+0

它是一个DataTemplate,所以你可以这样做。我只是在那里放了一个按钮,但您可以添加所需的内容。 – tgpdyk

+0

我已经实现了上述,我现在能够得到正确的模板加载,但是,在我试图绑定到'消息'的合适的模板,但他们都是空的,我做错了什么?例如''但是当我运行应用程序时总是空白 –