Привязка WPT DataTemplate в зависимости от типа свойства - PullRequest
17 голосов
/ 16 февраля 2011

У меня есть коллекция объектов, привязанных к шаблону иерархических данных, у каждого из моих объектов есть свойство (назовем его Свойство «A») определенного типа.Этот тип варьируется среди каждого из объектов.

Если шаблон данных содержит изображение и некоторый текст, какой будет лучший способ изменить изображение, отображаемое в шаблоне, в зависимости от типа свойства "A".

Я знаю, что мог бы просто вставить это в конвертер и выполнить перевод привязки вручную в коде, но, учитывая все возможности связывания, доступные в WPF, я думаю, что, возможно, есть лучший способ.

Ответы [ 3 ]

34 голосов
/ 16 февраля 2011

Это довольно просто сделать в шаблоне данных, если вы создаете локальные шаблоны данных и используете ContentPresenter. Этот шаблон представляет объекты типа MyObject, отображающие изображение, источник которого определяется типом свойства A рядом с TextBlock, которое отображает содержимое свойства Text:

<DataTemplate DataType="{x:Type MyObject}">
   <StackPanel Orientation="Horizontal">
      <StackPanel.Resources>
         <DataTemplate DataType="{x:Type Thing1}">
            <Image Source="thing1.png"/>
         </DataTemplate>
         <DataTemplate DataType="{x:Type Thing2}">
            <Image Source="thing2.png"/>
         </DataTemplate>
      </StackPanel.Resources>
      <ContentPresenter Content="{Binding A}"/>
      <TextBlock Text="{Binding Text}"/>
   </StackPanel>
</DataTemplate>

Если вы хотите использовать для этого стили, вместо этого вы столкнетесь с проблемой, потому что триггеры данных хотят посмотреть значения свойств, а type свойства A сама по себе не выставляется как собственность.

Если, конечно, вы не реализуете:

public Type AType { get { return A.GetType(); } }

(Вам также потребуется повысить PropertyChanged для AType, когда значение A изменится.) После того, как вы это сделаете, вы сможете реализовать триггер данных в стиле, например:

<Style TargetType="Image">
   <Setter Property="Source" Value="default.png"/>
   <Style.Triggers>
      <DataTrigger Binding="{Binding AType}" Value="{x:Type Thing1}">
         <Setter Property="Source" Value="thing1.png"/>
      </DataTrigger>
      <DataTrigger Binding="{Binding AType}" Value="{x:Type Thing2}">
         <Setter Property="Source" Value="thing2.png"/>
      </DataTrigger>
   </Style.Triggers>
</Style>
1 голос
/ 16 февраля 2011

DataTemplateSelector не кажется хорошим выбором, так как у вас один и тот же шаблон для всех значений A.

Использование DataTriggers:

<DataTemplate>
    <StackPanel>
        <Image x:Name="image" />
        <TextBlock>Your text</TextBlock>
    </StackPanel>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=A}" Value="ValueToCheck1">
            <DataTrigger.Setters>
                <Setter Property="Source" Value="Image1.png" TargetName="image" />
            </DataTrigger.Setters>
        </DataTrigger>
        <DataTrigger Binding="{Binding Path=A}" Value="ValueToCheck2">
            <DataTrigger.Setters>
                <Setter Property="Source" Value="Image2.png" TargetName="image" />
            </DataTrigger.Setters>
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

Не проверял, но идея такая.

1 голос
/ 16 февраля 2011

Я думаю, вы можете сделать это с помощью триггеров .

<Image.Style>
    <Style TargetType="{x:Type Image}">
        <Setter Property="Source" Value="Path">
        <Style.Triggers>
            <DataTrigger Binding="{Binding TheProperty}" Value="TheValue">
                <Setter Property="Source" Value="NewPath"/>
            </DataTrigger>
        </Style.Triggers>
     </Style>
</Image.Style>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...