2016-01-06 81 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

我已經實現了上述,我現在能夠得到正確的模板加載,但是,在我試圖綁定到'消息'的合適的模板,但他們都是空的,我做錯了什麼?例如''但是當我運行應用程序時總是空白 –