C# WPF - 如何组合数据触发器和触发器?

标签 c# wpf xaml

我不知道是否需要结合DataTrigger & Trigger,如果有更好的方法请告诉我。

我的目标是,创建一个菜单(带有图标),图标会在遇到悬停或选定事件时发生变化。

这是一个定义所有菜单类型的枚举:

public enum PageTypes:byte
{
    NotSet = 0,
    HomePage = 1,
    ShopPage = 2,
    AboutPage = 3
}

然后我创建了一个 MenuItemModel 代表每个菜单项:

public class MenuItemModel : INotifyPropertyChanged
{
    private PageTypes _menuItemType = PageTypes.NotSet;
    public PageTypes MenuItemType { get { return _menuItemType; } set { if (value != _menuItemType) { _menuItemType = value; RaisePropertyChanged(() => MenuItemType); } } }

    private bool _isSelected = false;
    public bool IsSelected { get { return _isSelected; } set { if (value != _isSelected) { _isSelected = value; RaisePropertyChanged(() => IsSelected); } } }
}

好的,那我开始创建 UI。

<!-- MenuItem Template -->
<DataTemplate x:Key="MenuTemplate">
    <Button Command="{Binding ClickCommand}" CommandParameter="{Binding}">
        <Image>
            <Image.Style>
                <Style TargetType="Image">
                    <Setter Property="Source" Value="/Image/Home_normal.png"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding MenuItemType}" Value="ShopPage">
                            <Setter Property="Source" Value="/Image/Shop_normal.png"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding MenuItemType}" Value="AboutPage">
                            <Setter Property="Source" Value="/Image/About_normal.png"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Image.Style>
        </Image>
    </Button>
</DataTemplate>

到目前为止一切都很简单,但是当我尝试制作 mouseOver 和 Selected 效果时,问题来了。

例如,如果鼠标悬停在 home_normal.png 上,则应更改为 home_hover.png,如果 IsSelected 属性为 TRUE,图像应忽略悬停触发器,然后使用 home_selected.png。但是有 3 张图片,我怎么知道应该更改哪张图片?

<!-- MenuItem Template -->
<DataTemplate x:Key="MenuTemplate">
    <Button Command="{Binding ClickCommand}" CommandParameter="{Binding}">
        <Image>
            <Image.Style>
                <Style TargetType="Image">
                    <Setter Property="Source" Value="/Image/Home_normal.png"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding MenuItemType}" Value="ShopPage">
                            <Setter Property="Source" Value="/Image/Shop_normal.png"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding MenuItemType}" Value="AboutPage">
                            <Setter Property="Source" Value="/Image/About_normal.png"/>
                        </DataTrigger>

                        <!-- MY PLAN -->
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Source" Value="?_hover.png"/>
                        </Trigger>
                        <DataTrigger Binding="{Binding IsSelected}" Value="True">
                            <Setter Property="Source" Value="?_selected.png"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Image.Style>
        </Image>
    </Button>
</DataTemplate>

如果您在“我的计划”评论中看到问号,那就是我的问题:我应该在值字段中做什么?

最佳答案

您可以像这样使用 MultiDataTrigger。但是您应该为所有类型的页面添加相同的 3 个触发器。请注意,下一个触发器会覆盖下面的条件,并且条件的工作方式类似于逻辑与。

<p:Style.Triggers xmlns:p="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <DataTrigger Binding="{Binding MenuItemType}" Value="ShopPage">
        <Setter Property="Source" Value="/Image/Shop_normal.png"/>
    </DataTrigger>
    <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
            <Condition Binding="{Binding MenuItemType}" Value="ShopPage" />
            <Condition Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsMouseOver}" Value="true" />
        </MultiDataTrigger.Conditions>
        <Setter Property="Source" Value="/Image/Shop_MouseOver.png" />
    </MultiDataTrigger>
    <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
            <Condition Binding="{Binding MenuItemType}" Value="ShopPage" />
            <Condition Binding="{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsSelected}" Value="true" />
        </MultiDataTrigger.Conditions>
        <Setter Property="Source" Value="/Image/Shop_IsSelected.png" />
    </MultiDataTrigger>
</p:Style.Triggers>

关于C# WPF - 如何组合数据触发器和触发器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34193266/

相关文章:

c# - XAML 按钮在消除引用后未被垃圾回收

c# - 序列化 RichTextBox,包括大小、背景颜色、位置

c# - WPF ListBox Binding 每行产生一个字符

c# - 为什么 WPF DataGrid 的垂直滚动太大?

c# - WPF 绑定(bind) - 空字符串的默认值

wpf - 如何使用 DataTrigger 启动 Storyboard ?

c# - C#.Net 中的连接字符串

C# 从 html 字符串打印 html 文档

c# - WPF DragDropEffects 在 Drop 事件中未正确设置

c# - 从此代码片段中删除重复项