datatrigger pada enum untuk mengubah gambar

101

Saya punya tombol dengan gambar latar belakang tetap dan ingin menampilkan gambar overlay kecil di atasnya. Gambar hamparan mana yang akan dipilih bergantung pada properti ketergantungan ( LapCounterPingStatus) dari viewmodel yang sesuai.

Inilah yang saya dapatkan sejauh ini:

<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>

Bagian yang relevan dari model tampilan saya

public class ConfigurationViewModel
{
    public enum PingStatus { PING_UNKNOWN, PING_SUCCESS, PING_FAILURE };

    public PingStatus LapCounterPingStatus
    {
        get { return _lapCounterPingStatus; }
        set
        {
            _lapCounterPingStatus = value;
            RaisePropertyChanged(LapCounterPingStatusPropertyName);
        }
    }
}

Saat ini, tidak ada gambar overlay sama sekali yang ditampilkan. Apa yang salah?


MEMPERBARUI

Jendela jejak IDE saya ditampilkan System.ArgumentExceptiondan System.FormatException. Mungkinkah sumber masalah adalah jenis enumerasi yang tidak diketahui PingStatusdi XAML?

nabulke
sumber
Terkait: stackoverflow.com/q/10250925/590790 Meskipun orang ini sudah berhasil.
Steven Jeuris

Jawaban:

249

Anda memerlukan 2 hal agar ini berfungsi:

1 - Tambahkan xmlnsreferensi di elemen root file XAML Anda, ke namespace tempat Enum Anda ditentukan:

<UserControl ...
xmlns:my="clr-namespace:YourEnumNamespace;assembly=YourAssembly"> 

2 - di Valueproperti DataTrigger, gunakan {x:Static}formulir:

 <DataTrigger Binding="{Binding Path=LapCounterPingStatus}" Value="{x:Static my:PingStatus.PING_UNKNOWN}">

Perhatikan bahwa tipe Enum harus diawali dengan awalan xmlns yang Anda tentukan di atas.

Edit:

Jika Enum Anda dideklarasikan di dalam kelas, Anda perlu menggunakan sintaks:

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

sebagai contoh:

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

Federico Berasategui
sumber
1
Saya menambahkan xmlnsseperti ini: xmlns:local="clr-namespace:MyCompany.Testbench"dan pemicunya seperti itu <DataTrigger Binding="{Binding Path=LapCounterPingStatus}" Value="{x:Static local:PingStatus.PING_UNKNOWN}">. Tidak, saya mendapatkan kesalahan Cannot find the type 'PingStatus'.
nabulke
1
enum PingStatusdidefinisikan di dalam kelas MyCompany.TestBench.ConfigurationViewModel. Apakah saya harus menambahkan nama kelas di suatu tempat?
nabulke
3
Terima kasih. Saya tidak dapat menemukan sintaks untuk tipe bersarang di mana pun. Di mana sintaks "+" didokumentasikan? Saya tidak dapat menemukannya di MSDN atau di buku WPF yang saya miliki. Saya pikir itu harus di x: Static Markup Extension tapi ternyata tidak.
skst
1
@skst Simbol + membedakan tipe yang mengandung dari namespace bertingkat. Type t = typeof (System.Environment.SpecialFolder); Console.WriteLine (t.FullName); // prints System.Environment+SpecialFolder
3

Contoh kerja lengkap untuk WPF + MVVM.

Diuji pada MSVC 2017.

Dalam tampilan:

<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>

Jika menggunakan ReSharper, dan jika DataContext diatur dengan benar, akan ada intellisense ketika anda menekan .setelah StatusIcon, yaitu ia akan menampilkan sifat-sifat enum yang Debug, Info, Warningatau Error.

Jika menggunakan ReSharper, itu akan menyarankan pembaruan berikut ke namespace di header untuk file XAML (bagus seperti itu):

xmlns:my="clr-namespace:Class.Path.MyViewModel;assembly=MyAssembly"

Dan VieModel:

public enum StatusIcon
{
    Debug,
    Info,
    Warning,
    Error
}

public class MyViewModel
{
    public StatusIcon StatusIcon { get; }
}

Kami juga menggunakan Fodyuntuk pengikatan otomatis.

Contango
sumber
Apakah Anda mengacu pada proyek PropertyChanged Fody?
UuDdLrLrSs