在WPF中应用条件样式

时间:2015-09-03 19:02:39

标签: c# wpf xaml styles

我遇到了一个问题,需要在菜单项上应用条件样式,这里有点来自我的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>

在上面,IsEligibleToDisplay一个bool属性,MyVisibilityConverter根据True或false将Visibility设置为Visible或Hidden。

有什么期望?

如果隐藏“Menu3”的可见性,即IsEligibleToDisplay = false,则“Menu2”的样式应为Style =“{DynamicResource M_Right}”,否则Style =“{DynamicResource M_Middle}”

有点像(它只是假设,请不要检查语法 - 错误:)):

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

任何帮助都将受到高度赞赏!

3 个答案:

答案 0 :(得分:2)

您可能需要考虑的一种方法是使用ItemContainerStyleSelector属性在Menu控件上使用样式选择器。

ItemContainerStyleSelector Property

这将允许您创建自定义逻辑,以便在您的各个MenuItem上设置所需的样式。

答案 1 :(得分:2)

如果您的要求是仅使用XAML,我猜您可以使用DataTriggers

您无法直接在Style属性中设置“条件”,但必须将其移至Style声明中。

这个小样本可能可以帮助您解决任务:

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

我只使用按钮将Menu3从Visible切换为Hidden,反之亦然。我使用了一个简单的处理程序:

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

我希望这个解决方案适合你。

答案 2 :(得分:0)

也许您可以尝试使用基于IsEligibleToDisplay属性的数据触发器并使用通用模板。

将这个例子放在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>