Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# WPF - How to Combine datatrigger and trigger?

Tags:

c#

wpf

xaml

I don't know if need to combine DataTrigger & Trigger, if there's better way please tell me.

My goal is, to create a menu(with icons), icons will change while meet hover or selected event.

Here's an enum define all menu types:

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

Then I created a MenuItemModel represent each menu item:

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); } } }
}

Ok, then I begin to create 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>

till now everything is very easy, but when I try to make mouseOver and Selected effect, problem comes.

for example, if mouse over home_normal.png, it should change to home_hover.png, if IsSelected property is TRUE, image should be ignore hover trigger then use home_selected.png. But there's 3 image, how do I know what image should change?

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

If you can see the question mark in "MY PLAN" comment, that would be my question: what should I do in the Value field?

like image 721
Oh My Dog Avatar asked Dec 10 '15 03:12

Oh My Dog


1 Answers

You can use MultiDataTrigger like this. But you should add same 3 triggers for all types of pages. Note that next trigger overrides below and conditions works like logical AND.

<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>
like image 51
bars222 Avatar answered Nov 15 '22 08:11

bars222