Условные FrameworkElements в зависимости от DataContext
-
05-07-2019 - |
Вопрос
В моем приложении M-V-VM я должен показать аватар пользователя. Изображение предоставляется в свойстве типа ImageSource объекта ViewModel. Вот что у меня есть сейчас:
<Image Source="{Binding Path=UserAvatar}"/>
Однако у некоторых пользователей может не быть настроенного аватара, поэтому UserAvatar имеет значение null
. В этом случае я хочу показать аватар по умолчанию. Никто, кроме представления, не должен знать об изображении по умолчанию, потому что это просто вопрос представления.
Итак, как я могу показать изображение с заданным ImageSource или конкретным ресурсом, если ImageSource равен null
. Должен ли я использовать какой-либо тип DataTemplate с DataTriggers? С тех пор я использовал их только для ItemsControls, поэтому я не знаю.
Решение
Как вы уже догадались, шаблоны и триггеры действительно ваши друзья здесь.
Вот реализация, использующая ContentControl
:
<ContentControl Content="{Binding Path=UserAvatar}">
<ContentControl.ContentTemplate>
<DataTemplate>
<Image x:Name="image" Source="{Binding}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding}" Value="{x:Null}">
<Setter TargetName="image" Property="Source" Value="--your awesome default image here--" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
И в ситуации, когда по умолчанию у вас нет ImageSource
, и вы хотите немного поиграть с другими элементами управления, вы всегда можете прибегнуть к свойству Visibilty
: р>
<ContentControl Content="{Binding Path=UserAvatar}">
<ContentControl.ContentTemplate>
<DataTemplate>
<Grid>
<Image x:Name="image" Source="{Binding}" />
<Canvas x:Name="defaultImage" Visibility="Collapsed" />
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding}" Value="{x:Null}">
<Setter TargetName="image" Property="Visibility" Value="Collapsed" />
<Setter TargetName="defaultImage" Property="Visibility" Value="Visible" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
Надеюсь, это поможет ..