datatrigger trên enum để thay đổi hình ảnh


100

Tôi có một nút với hình nền cố định và muốn hiển thị một hình ảnh lớp phủ nhỏ trên đó. Hình ảnh lớp phủ nào để chọn phụ thuộc vào thuộc tính phụ thuộc ( LapCounterPingStatus) của mô hình theo.

Đây là những gì tôi nhận được cho đến nay:

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

Các phần có liên quan trong mô hình xem của tôi

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

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

Hiện tại, không có hình ảnh lớp phủ nào được hiển thị. Điều gì có thể sai?


CẬP NHẬT

Cửa sổ theo dõi IDE của tôi đang hiển thị System.ArgumentExceptionSystem.FormatException. Nguồn vấn đề có thể là một kiểu liệt kê không xác định, tôi PingStatuslà XAML?


Liên quan: stackoverflow.com/q/10250925/590790 Mặc dù anh chàng này đã làm cho nó hoạt động rồi.
Steven Jeuris 17/12/12

Câu trả lời:


247

Bạn cần 2 điều để làm cho nó hoạt động:

1 - Thêm xmlnstham chiếu trong phần tử gốc của tệp XAML của bạn, vào không gian tên nơi Enum của bạn được xác định:

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

2 - trong thuộc Valuetính của DataTrigger, sử dụng {x:Static}biểu mẫu:

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

Lưu ý rằng kiểu Enum phải được bắt đầu bằng tiền tố xmlns mà bạn đã xác định ở trên.

Biên tập:

Nếu Enum của bạn được khai báo bên trong một lớp, bạn cần sử dụng cú pháp:

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

ví dụ:

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


1
Tôi đã thêm xmlnsnhư thế này: xmlns:local="clr-namespace:MyCompany.Testbench"và trình kích hoạt như vậy <DataTrigger Binding="{Binding Path=LapCounterPingStatus}" Value="{x:Static local:PingStatus.PING_UNKNOWN}">. Không, tôi nhận lỗi Cannot find the type 'PingStatus'.
nabulke

1
enum PingStatusđược định nghĩa bên trong lớp MyCompany.TestBench.ConfigurationViewModel. Tôi có phải thêm tên lớp vào đâu đó không?
nabulke

3
Cảm ơn bạn. Tôi không thể tìm thấy cú pháp cho một kiểu lồng nhau ở bất kỳ đâu. Cú pháp "+" được ghi ở đâu? Tôi không thể tìm thấy nó trong MSDN hoặc trong các sách WPF mà tôi có. Tôi nghĩ nó phải ở trong x: Static Markup Extension nhưng không phải vậy.
trượt

1
@skst Biểu tượng + phân biệt kiểu chứa với không gian tên lồng nhau. Type t = typeof (System.Environment.SpecialFolder); Console.WriteLine (t.FullName); // prints System.Environment+SpecialFolder


2

Hoàn thành ví dụ làm việc cho WPF + MVVM.

Đã thử nghiệm trên MSVC 2017.

Theo quan điểm:

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

Nếu sử dụng ReSharper, và nếu DataContext được thiết lập đúng, sẽ có IntelliSense khi bạn nhấn .sau StatusIcon, tức là nó sẽ hiển thị các thuộc tính của enum mà Debug, Info, Warninghoặc Error.

Nếu sử dụng ReSharper, nó sẽ đề xuất bản cập nhật sau cho không gian tên trong tiêu đề cho tệp XAML (nó tốt như vậy):

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

Và VieModel:

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

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

Chúng tôi cũng sử dụng Fodyđể ràng buộc tự động.


Bạn đang tham khảo dự án PropertyChanged của Fody?
UuDdLrLrSs
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.