2016-01-06 7 views
0

Может ли кто-нибудь определить, почему следующее не работает, пожалуйста, я пытаюсь реализовать окно сообщения чата, в котором каждое сообщение будет отображать другой стиль, зависящий от MessageDirection. Для этого я использую ItemsControl, который связан с Messages собственностиItemsControl различный шаблон на основе содержимого

В классе ChatWindow я следующее

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 
} 

Когда я запускаю этот код, все работает нормально, и метод OnContentChanged выполняется один раз для каждого элемента в коллекции Messages. Проблема заключается в том, что и InboundTemplate, и OutboundTemplate являются null.

Я действительно не могу понять, в чем проблема, и почему оба шаблона - это null, любая помощь значительно ценится.

+0

Может 'Content' свойство установлено перед тем входящих и исходящих шаблонов. Я думаю, что было бы лучше использовать пользовательский ['DataTemplateSelector'] (https://msdn.microsoft.com/en-us/library/system.windows.controls.datatemplateselector (v = vs.110) .aspx) – dkozl

+0

Do у вас есть пример реализации на основе вышеизложенного –

+0

У меня нет доступа к ПК в настоящий момент, но сайт MSDN по приведенной выше ссылке должен иметь один – dkozl

ответ

0

Действительно, вы можете использовать DataTemplateSelector.

Но другой вариант использовать DataTemplate + ContentControl и стиль:

Первое, забросьте MessageContentPresenter класс, как мы это не нужно. Следовательно, вам необходимо удалить ItemsControl.ItemTemplate со своего XAML.

Во-вторых, добавьте DataTemplate + ContentControl и стиль в свое 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

Я реализовал выше, и теперь я могу получить правильный шаблон для загрузки, однако, внутри шаблона, который я пытаюсь связать с полномочиями «Message», но все они пустые, что я делаю неправильно? Например, ', но когда я запускаю приложение, это всегда пусто –