Datatrigger on enum изменить изображение
У меня есть кнопка с фиксированным фоновым изображением и хотелось бы показать небольшое оверлейное изображение поверх нее. Какое оверлейное изображение выбирается, зависит от свойства зависимостей (LapCounterPingStatus
) от соответствующей модели просмотра.
Это то, что я получил до сих пор:
<Button>
<Grid>
<Image Stretch="None"> <!-- Background Image -->
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="/Images/Pingn.png"/>
</Style>
</Image.Style>
</Image>
<Image Stretch="None" Panel.ZIndex="1"> <!-- Small Overlay Image -->
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=LapCounterPingStatus}" Value="PingStatus.PING_UNKNOWN">
<Setter Property="Source" Value="/Images/RefreshOverlayn.png"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=LapCounterPingStatus}" Value="PingStatus.PING_FAILURE">
<Setter Property="Source" Value="/Images/ErrorOverlayn.png"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=LapCounterPingStatus}" Value="PingStatus.PING_SUCCESS">
<Setter Property="Source" Value="/Images/CheckmarkOverlayn.png"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Grid>
</Button>
Соответствующие части моей модели просмотра
public class ConfigurationViewModel
{
public enum PingStatus { PING_UNKNOWN, PING_SUCCESS, PING_FAILURE };
public PingStatus LapCounterPingStatus
{
get { return _lapCounterPingStatus; }
set
{
_lapCounterPingStatus = value;
RaisePropertyChanged(LapCounterPingStatusPropertyName);
}
}
}
В настоящий момент не отображается оверлейное изображение. Что может быть неправильным?
UPDATE
В окне трассировки моей IDE отображается System.ArgumentException
и System.FormatException
.
Может ли источник проблемы быть неизвестным типом перечисления PingStatus
im the XAML?
Ответы
Ответ 1
Вам нужно 2 вещи, чтобы заставить это работать:
1 - добавьте ссылку xmlns
в корневой элемент вашего файла XAML в пространство имен, где определено ваше перечисление:
<UserControl ...
xmlns:my="clr-namespace:YourEnumNamespace;assembly=YourAssembly">
2 - в свойстве Value
DataTrigger
используйте форму {x:Static}
:
<DataTrigger Binding="{Binding Path=LapCounterPingStatus}" Value="{x:Static my:PingStatus.PING_UNKNOWN}">
Обратите внимание, что тип Enum должен иметь префикс префикса xmlns, определенного выше.
Edit:
Если ваш Enum объявлен внутри класса, вам нужно использовать синтаксис:
{x:Static namespace:ClassName+EnumName.EnumValue}
например:
{x:Static my:ConfigurationViewModel+PingStatus.PING_UNKNOWN}
Ответ 2
Полный рабочий пример для WPF + MVVM.
Проверено на MSVC 2017.
По мнению:
<TextBlock Text="Some text to be colored by an enum">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding StatusIcon}" Value="{x:Static my:StatusIcon.Warning}">
<Setter Property="Foreground" Value="Yellow"/>
</DataTrigger>
<DataTrigger Binding="{Binding StatusIcon}" Value="{x:Static my:StatusIcon.Error}">
<Setter Property="Foreground" Value="Red}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
Если вы используете ReSharper и если DataContext настроен правильно, при нажатии .
после StatusIcon
будет значение intellisense, т.е. будут отображаться свойства перечисления, которые Debug
, Info
, Warning
или Error
.
При использовании ReSharper будет предложено следующее обновление пространства имен в заголовке файла XAML (его
хорошо как то):
xmlns:my="clr-namespace:Class.Path.MyViewModel;assembly=MyAssembly"
И VieModel:
public enum StatusIcon
{
Debug,
Info,
Warning,
Error
}
public class MyViewModel
{
public StatusIcon StatusIcon { get; }
}
Мы также используем Fody
для автоматической привязки.