görüntüyü değiştirmek için enum üzerinde veri tetikleyici


103

Sabit bir arka plan resmine sahip bir düğmem var ve bunun üzerinde küçük bir bindirme resmi göstermek istiyorum. Hangi bindirme görüntüsünün LapCounterPingStatusseçileceği, ilgili görünüm modelinin bağımlılık özelliğine ( ) bağlıdır .

Şu ana kadar elde ettiğim şey bu:

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

Görünüm modelimin alakalı bölümleri

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

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

Şu anda hiçbir bindirme görüntüsü görüntülenmiyor. Ne yanlış olabilir?


GÜNCELLEME

Benim IDE İz penceresi gösteriyor System.ArgumentExceptionve System.FormatException. Sorun kaynağı PingStatus, XAML'de bilinmeyen bir numaralandırma türü olabilir mi?


İlgili: stackoverflow.com/q/10250925/590790 Bu adam zaten çalışıyor olmasına rağmen.
Steven Jeuris

Yanıtlar:


251

Bunu çalıştırmak için 2 şeye ihtiyacınız var:

1 - xmlnsEnum'unuzun tanımlandığı ad alanına XAML dosyanızın kök öğesinde bir başvuru ekleyin :

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

2 - Valuemülkiyetinde DataTriggerşu {x:Static}formu kullanın :

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

Enum türünün, yukarıda tanımladığınız xmlns önekiyle ön eklenmesi gerektiğine dikkat edin.

Düzenle:

Enum'unuz bir sınıf içinde bildirilmişse sözdizimini kullanmanız gerekir:

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

Örneğin:

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


1
Şöyle ekledim xmlns: xmlns:local="clr-namespace:MyCompany.Testbench"ve bunun gibi tetikleyici <DataTrigger Binding="{Binding Path=LapCounterPingStatus}" Value="{x:Static local:PingStatus.PING_UNKNOWN}">. Hayır, hatayı alıyorum Cannot find the type 'PingStatus'.
nabulke

1
enum PingStatussınıf içinde tanımlanır MyCompany.TestBench.ConfigurationViewModel. Sınıf adını bir yere eklemem gerekiyor mu?
nabulke

3
Teşekkür ederim. İç içe geçmiş bir türün sözdizimini hiçbir yerde bulamadım. "+" Sözdizimi nerede belgelenir? Bunu MSDN'de veya sahip olduğum WPF kitaplarında bulamıyorum. X: Static Markup Extension içinde olması gerektiğini düşündüm ama değil.
skst

1
@skst + simgesi, içeren türü iç içe geçmiş bir ad alanından ayırır. Type t = typeof (System.Environment.SpecialFolder); Console.WriteLine (t.FullName); // prints System.Environment+SpecialFolder


3

WPF + MVVM için eksiksiz çalışılmış örnek.

MSVC 2017'de test edilmiştir.

Görünümde:

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

DataContext düzgün bir şekilde kurulmuş olup olmadığını vurduğunda ReSharper kullanılıyorsa, ve, Intellisense olacak .SONRA StatusIcono vardır enum özelliklerini gösterecektir, ie Debug, Info, Warningveya Error.

ReSharper kullanılıyorsa, XAML dosyası için başlıktaki ad alanına aşağıdaki güncellemeyi önerir (bunun gibi iyidir):

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

Ve VieModel:

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

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

FodyOtomatik bağlama için de kullanıyoruz .


Fody'nin PropertyChanged projesinden mi bahsediyorsunuz?
UuDdLrLrSs

0

Enum değerini DataTrigger Value olarak ayarlayabilirsiniz ... MSVC 2017'de test edilmiştir.

<TextBlock Text="Some text to be colored by an enum">
    <TextBlock.Style>
        <Style TargetType="{x:Type TextBlock}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding StatusIcon}" Value="Warning">
                    <Setter Property="Foreground" Value="Yellow"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding StatusIcon}" Value="Error">
                    <Setter Property="Foreground" Value="Red}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.