简体   繁体   English

在WPF中应用条件样式

[英]Apply conditional styling in WPF

I ran through one issue, need to apply conditional styling on Menu Item, here is a bit from my Code-Snippet: 我遇到了一个问题,需要在菜单项上应用条件样式,这是我的代码片段的一部分:

<Grid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,10,0,0">
    <Menu HorizontalAlignment="Left" KeyboardNavigation.TabNavigation="Once" Background="Transparent" d:LayoutOverrides="Height">
        <MenuItem Header="Menu1" Style="{DynamicResource M_Left}"  />
        <MenuItem Header="Menu2" Style="{DynamicResource M_Middle}" />
        <MenuItem Header="Menu3" Style="{DynamicResource M_Right}" Visibility="{Binding IsEligibleToDisplay, Converter={StaticResource MyVisibilityConverter}}" />
    </Menu>
</Grid>

In above, IsEligibleToDisplay a bool property and MyVisibilityConverter sets Visibility either to Visible or Hidden on the basis of True or false. 在上面,IsEligibleToDisplay是bool属性,而MyVisibilityConverter基于True或false将Visibility设置为Visible或Hidden。

What is expected? 期望什么?

If Visibility of "Menu3" is Hidden ie IsEligibleToDisplay = false then Style of "Menu2" should be Style="{DynamicResource M_Right}" otherwise Style="{DynamicResource M_Middle}" 如果隐藏了“ Menu3”的可见性,即IsEligibleToDisplay = false,则“ Menu2”的样式应为Style =“ {DynamicResource M_Right}”,否则为Style =“ {DynamicResource M_Middle}”

Something like (its just hypothetic, please do not check syntax - its wrong:)): 诸如此类(只是假设,请不要检查语法-错误:)):

<MenuItem Header="Menu2" Style="IsEligibleToDisplay ? {DynamicResource M_Middle} : {DynamicResource M_Right}" />  

Any help will be highly appreciated! 任何帮助将不胜感激!

One approach you might want to consider, is using a style selector on your Menu control using the ItemContainerStyleSelector property. 您可能要考虑的一种方法是使用ItemContainerStyleSelector属性在Menu控件上使用样式选择器。

ItemContainerStyleSelector Property ItemContainerStyleSelector属性

This will allow you to create custom logic to set the styles you need on your individual MenuItems. 这将允许您创建自定义逻辑来设置各个MenuItem所需的样式。

If your requirement is to use just XAML, I guess you can use DataTriggers . 如果您只需要使用XAML,我想您可以使用DataTriggers

You cannot set your "condition" directly in the Style property, but you have to move it inside the Style declaration. 您不能直接在Style属性中设置“条件”,但是必须在Style声明中移动它。

Probably this small sample can help you in resolving your task: 这个小样本可能可以帮助您解决任务:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="300" Width="400">

    <Window.Resources>

        <Style x:Key="ConditionalStyle" TargetType="MenuItem">
            <Style.Triggers>
                <DataTrigger Binding="{Binding ElementName=Menu3, Path=Visibility}" Value="Visible">
                    <Setter Property="Foreground" Value="Red" />
                </DataTrigger>
                <DataTrigger Binding="{Binding ElementName=Menu3, Path=Visibility}" Value="Hidden">
                    <Setter Property="Foreground" Value="Green" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>


    <StackPanel>
        <Menu HorizontalAlignment="Left" KeyboardNavigation.TabNavigation="Once" Background="Transparent">
            <MenuItem Header="Menu1" />
            <MenuItem Header="Menu2" Style="{DynamicResource ConditionalStyle}" />
            <MenuItem Name="Menu3" Header="Menu3" Visibility="Visible" />
        </Menu>

        <Button Content="ClickMe" Margin="10" Click="Button_Click" />
    </StackPanel>
</Window>

I used the button just to switch Menu3 from Visible to Hidden and viceversa. 我仅使用按钮将Menu3从“可见”切换为“隐藏”,反之亦然。 I used a simple handler: 我使用了一个简单的处理程序:

private void Button_Click(object sender, RoutedEventArgs e)
{
    if(Menu3.Visibility == System.Windows.Visibility.Visible)
    {
        Menu3.Visibility = System.Windows.Visibility.Hidden;
        return;
    }
    Menu3.Visibility = System.Windows.Visibility.Visible;
}

I hope this solution is suitable for you. 希望此解决方案适合您。

Maybe you can try to use a datatrigger based on IsEligibleToDisplay property and use a common template. 也许您可以尝试使用基于IsEligibleToDisplay属性的数据触发器并使用通用模板。

Put this exemple in ResourceDictionary : 将此示例放在ResourceDictionary中:

        <!-- The visibility converter -->
        <BooleanToVisibilityConverter x:Key="MyVisibilityConverter" />

        <!-- Common template -->
        <ControlTemplate x:Key="myContent">
            <Label Content="{Binding Header, RelativeSource={RelativeSource TemplatedParent}}" 
                       HorizontalAlignment="Center"
                       HorizontalContentAlignment="Center"
                      Padding="0"
                       Height="20" 
                       Width="80" 
                       Background="Green"/>

        </ControlTemplate>

        <!-- M_Left style -->
        <Style x:Key="M_Left"
               TargetType="MenuItem">
            <Setter Property="Background"
                    Value="Yellow" />
        </Style>

        <Style x:Key="M_Middle"
               TargetType="MenuItem">
            <Setter Property="Background"
                    Value="Red" />
            <Style.Triggers>
                <!-- trigger based on IsEligibleToDisplay property -->
                <DataTrigger Binding="{Binding IsEligibleToDisplay}"
                             Value="false">
                    <!-- If false then apply common template to middle menu item. -->
                    <Setter Property="Template"
                            Value="{DynamicResource myContent}" />
                </DataTrigger>
            </Style.Triggers>
        </Style>

        <Style x:Key="M_Right"
               TargetType="MenuItem">
            <Setter Property="Template"
                    Value="{DynamicResource myContent}" />
        </Style>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM