C# 枚举上的数据触发器以更改图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13917033/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 10:05:30  来源:igfitidea点击:

datatrigger on enum to change image

c#wpf

提问by nabulke

I've got a button with a fixed background image and would like to show a small overlay image on top of it. Which overlay image to chose depends on a dependency property (LapCounterPingStatus) of the according viewmodel.

我有一个带有固定背景图像的按钮,我想在它上面显示一个小的叠加图像。选择哪个叠加图像取决于LapCounterPingStatus相应视图模型的依赖属性 ( )。

This is what I got so far:

这是我到目前为止得到的:

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

Relevant parts of my viewmodel

我的视图模型的相关部分

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

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

Right now, no overlay image at all is displayed. What could be wrong?

现在,根本没有显示叠加图像。可能有什么问题?



UPDATE

更新

Trace window of my IDE is showing System.ArgumentExceptionand System.FormatException. Could the problem source be a unknown type of enumeration PingStatusim the XAML?

我的 IDE 的跟踪窗口显示System.ArgumentExceptionSystem.FormatException. 问题来源可能是PingStatusXAML 中未知类型的枚举吗?

采纳答案by Federico Berasategui

You need 2 things to get this working:

您需要两件事才能使其正常工作:

1 - Add an xmlnsreference in the root element of your XAML file, to the namespace where your Enum is defined:

1 -xmlns在 XAML 文件的根元素中添加对定义 Enum 的命名空间的引用:

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

2 - in the Valueproperty of the DataTrigger, use the {x:Static}form:

2 - 在 的Value属性中DataTrigger,使用以下{x:Static}形式:

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

Notice that the Enum type must be prefixed with the xmlns prefix you defined above.

请注意, Enum 类型必须以您在上面定义的 xmlns 前缀作为前缀。

Edit:

编辑:

If your Enum is declared inside a class you need to use the syntax:

如果您的 Enum 在类中声明,您需要使用以下语法:

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

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

for example:

例如:

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

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

回答by Contango

Complete worked example for WPF + MVVM.

WPF + MVVM 的完整工作示例。

Tested on MSVC 2017.

在 MSVC 2017 上测试。

In the view:

在视图中:

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

If using ReSharper, and if the DataContext is set up properly, there will be intellisense when you hit the .after StatusIcon, i.e. it will show the properties of the enum which are Debug, Info, Warningor Error.

如果使用ReSharper的,如果DataContext设置不当,会出现智能感知当你到了.之后StatusIcon,也就是说,它会显示枚举它们的性质DebugInfoWarningError

If using ReSharper, it will suggest the following update to the namespace in the header for the XAML file(its good like that):

如果使用 ReSharper,它将建议对 XAML 文件标头中的命名空间进行以下更新(就像那样):

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

And the VieModel:

和 VieModel:

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

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

We also use Fodyfor automated binding.

我们也Fody用于自动绑定。