тригер даних на enum для зміни зображення


100

У мене є кнопка із фіксованим фоновим зображенням, і я хотів би показати невелике накладене зображення поверх неї. Яке зображення накладеного зображення залежить від властивості залежності ( 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);
        }
    }
}

Зараз накладене зображення взагалі не відображається. Що може бути не так?


ОНОВЛЕННЯ

Вікно трасування моєї IDE відображається System.ArgumentExceptionі System.FormatException. Чи може джерелом проблеми бути невідомий тип перерахування PingStatusв XAML?


Пов’язані: stackoverflow.com/q/10250925/590790 Хоча цей хлопець уже працював.
Стівен Джеуріс

Відповіді:


247

Вам потрібно 2 речі, щоб це працювало:

1 - Додайте xmlnsпосилання в кореневому елементі вашого файлу XAML до простору імен, де визначено ваш Enum:

<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, який ви визначили вище.

Редагувати:

Якщо ваш Enum оголошено всередині класу, вам потрібно використовувати синтаксис:

{x:Static namespace:ClassName+EnumName.EnumValue}

наприклад:

{x:Static my:ConfigurationViewModel+PingStatus.PING_UNKNOWN}


1
Я додав xmlnsтак: xmlns:local="clr-namespace:MyCompany.Testbench"і тригер такий <DataTrigger Binding="{Binding Path=LapCounterPingStatus}" Value="{x:Static local:PingStatus.PING_UNKNOWN}">. Ні, я отримую помилку Cannot find the type 'PingStatus'.
nabulke

1
enum PingStatusвизначається всередині класу MyCompany.TestBench.ConfigurationViewModel. Чи потрібно десь додавати назву класу?
nabulke

3
Дякую. Я ніде не міг знайти синтаксис для вкладеного типу. Де задокументовано синтаксис "+"? Я не можу знайти його в MSDN або в книгах WPF, які у мене є. Я думав, що це має бути у x: Static Markup Extension, але це не так.
skst

1
@skst Символ + відрізняє тип вмісту від вкладеного простору імен. Type t = typeof (System.Environment.SpecialFolder); Console.WriteLine (t.FullName); // prints System.Environment+SpecialFolder


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 налаштований правильно, то буде IntelliSense , коли ви потрапили .після того, як StatusIcon, тобто він буде показувати властивості перерахування , які є 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для автоматичного прив'язки.


Ви маєте на увазі проект Fody's PropertyChanged?
UuDdLrLrSs
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.