根据另一种风格激活的风格?

时间:2010-12-24 23:38:35

标签: c# .net wpf vb.net xaml

我正在尝试创建一个样式,只有在样式引用的元素的父元素具有另一种特定样式时才会应用该样式。有点像在CSS中你可以做“.class1 .class2”来指定只有“class2”主题在类“class1”的元素中才适用。

我不希望使用任何形式的外部DLL或库来执行此任务。我想知道是否可以自己实施。

我尝试过使用MultiTriggers没有运气。

我有一个适用于所有TextBlocks的样式。我希望textblock执行以下操作:

如果textblock的字体大小为11且父元素的样式为“PinnedSuggestion”,请将前景色设置为“#FF505050”。

如果textblock的字体大小为11且父元素的样式为“Suggestion”,请将前景色设置为“#FFCCCCCC”。

我试图编写以使其工作的条件如下(font-size条件为true,但另一个条件不是)。这些条件位于适用于所有文本块的样式内。

                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=FontSize}" Value="11" />
                        <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=Style}" Value="{StaticResource PinnedSuggestion}" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="Foreground" Value="#FFFF5050"></Setter>
                </MultiDataTrigger>

我不确定在这种情况下我做错了什么。下面是“建议”样式的ListBoxItem样式。 PinnedSuggestion看起来完全相同(除了一些小的改动)。

<Style x:Key="Suggestion" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <Grid Name="Container" Margin="0,0,0,0">
                    <Rectangle Margin="0,2,0,2" Stroke="Black" Name="Background" SnapsToDevicePixels="True" RadiusX="7" RadiusY="7" Width="Auto" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></Rectangle>
                    <Rectangle Margin="2,4,2,4" Name="BackgroundTwo" StrokeThickness="3"  SnapsToDevicePixels="True" RadiusX="3" RadiusY="3" Width="Auto" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></Rectangle>
                    <ContentPresenter Margin="0"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

该ListBoxItem样式的contentpresenter包含我希望使用此技术的文本块。

所以,总结一下......

应用了“Suggestion”样式的ListBoxItem中将包含TextBlock。 TextBlock样式(由于其目标类型)将自动应用于该样式,并且我希望上述多重触发条件能够正常工作。

我的情况很难解释。我尽可能地解释了一切。

1 个答案:

答案 0 :(得分:2)

要检查其样式的父元素不是TextBlock的直接父元素;它在视觉树中可以任意高一些。所以你的第二个条件需要寻找像这样的特定类型的祖先:

<Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=Style}" Value="{StaticResource Suggestion}" />

这是一个完整的工作示例,使用.NET4进行测试:

<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="350" Width="525">
<Window.Resources>
    <Style x:Key="Suggestion" TargetType="{x:Type ListBoxItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Grid Name="Container" Margin="0,0,0,0">
                        <Rectangle Margin="0,2,0,2" Stroke="Blue" Name="Background" SnapsToDevicePixels="True" RadiusX="7" RadiusY="7" Width="Auto" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></Rectangle>
                        <Rectangle Margin="2,4,2,4" Name="BackgroundTwo" StrokeThickness="3"  SnapsToDevicePixels="True" RadiusX="3" RadiusY="3" Width="Auto" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></Rectangle>
                        <ContentPresenter Margin="0"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="PinnedSuggestion" TargetType="{x:Type ListBoxItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Grid Name="Container" Margin="0,0,0,0">
                        <Rectangle Margin="0,2,0,2" Stroke="Green" Name="Background" SnapsToDevicePixels="True" RadiusX="7" RadiusY="7" Width="Auto" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></Rectangle>
                        <Rectangle Margin="2,4,2,4" Name="BackgroundTwo" StrokeThickness="3"  SnapsToDevicePixels="True" RadiusX="3" RadiusY="3" Width="Auto" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></Rectangle>
                        <ContentPresenter Margin="0"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style x:Key="Neutral" TargetType="{x:Type ListBoxItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Grid Name="Container" Margin="0,0,0,0">
                        <Rectangle Margin="0,2,0,2" Stroke="Black" Name="Background" SnapsToDevicePixels="True" RadiusX="7" RadiusY="7" Width="Auto" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></Rectangle>
                        <Rectangle Margin="2,4,2,4" Name="BackgroundTwo" StrokeThickness="3"  SnapsToDevicePixels="True" RadiusX="3" RadiusY="3" Width="Auto" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"></Rectangle>
                        <ContentPresenter Margin="0"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style TargetType="{x:Type TextBlock}">
        <Style.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=FontSize}" Value="11" />
                    <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=Style}" Value="{StaticResource Suggestion}" />
                </MultiDataTrigger.Conditions>
                <Setter Property="Foreground" Value="Red"></Setter>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=FontSize}" Value="11" />
                    <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=Style}" Value="{StaticResource PinnedSuggestion}" />
                </MultiDataTrigger.Conditions>
                <Setter Property="Foreground" Value="Yellow"></Setter>
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Grid>
    <ListBox>
        <ListBoxItem Style="{StaticResource Neutral}">
            <TextBlock FontSize="10" Text="Style=Neutral, FontSize=10"/>
        </ListBoxItem>
        <ListBoxItem Style="{StaticResource Neutral}">
            <TextBlock FontSize="11" Text="Style=Neutral, FontSize=11"/>
        </ListBoxItem>
        <ListBoxItem Style="{StaticResource Suggestion}">
            <TextBlock FontSize="10" Text="Style=Suggestion, FontSize=10"/>
        </ListBoxItem>
        <ListBoxItem Style="{StaticResource Suggestion}">
            <TextBlock FontSize="11" Text="Style=Suggestion, FontSize=11"/>
        </ListBoxItem>
        <ListBoxItem Style="{StaticResource PinnedSuggestion}">
            <TextBlock FontSize="10" Text="Style=PinnedSuggestion, FontSize=10"/>
        </ListBoxItem>
        <ListBoxItem Style="{StaticResource PinnedSuggestion}">
            <TextBlock FontSize="11" Text="Style=PinnedSuggestion, FontSize=11"/>
        </ListBoxItem>
    </ListBox>
</Grid>