在我的C# / WPF / .NET 4.5应用程序中,我想实现一个Trigger在不改变控件颜色的情况下切换控件的背景不透明度。
通常要设置控件的背景画笔,我会使用以下内容Setter:
<Setter TargetName="TargetControl" Property="Background">
<Setter.Value>
<SolidColorBrush Color="Red" Opacity="0.2"/>
</Setter.Value>
Run Code Online (Sandbox Code Playgroud)
现在我处于一种情况,我只需要改变不透明度而不是颜色。在这种情况下,我的 setter 会是什么样子,我不在乎背景是什么颜色,但我想在更改不透明度的同时保留颜色?
这样做的原因是我正在研究ItemsControl背景颜色根据项目的变化而变化的地方AlternationIndex:
<ItemsControl ItemsSource="{Binding SomeCollection}" AlternationCount="6">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="GridWithin">
<!-- ... -->
</Grid>
<DataTemplate.Triggers>
<!-- Aternating colors for each row -->
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter TargetName="GridWithin" Property="Background">
<Setter.Value>
<SolidColorBrush Color="Red" Opacity="0.2"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter TargetName="AllGesturesDataTemplateGrid" Property="Background">
<Setter.Value>
<SolidColorBrush Color="Green" Opacity="0.2"/>
</Setter.Value>
</Setter>
</Trigger>
<!-- ... -->
<!-- Highlight when a hit is registered -->
<DataTrigger>
<DataTrigger.Conditions>
<Condition Binding="{Binding IsHit}" Value="True" />
</MultiDataTrigger.Conditions>
<!-- The culprit -->
<Setter TargetName="GridWithin" Property="Background">
<Setter.Value>
<SolidColorBrush Opacity="0.7"/>
</Setter.Value>
</Setter>
<!-- /culprit -->
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
我花了一点时间才想到这样做的最佳方法……结果证明这比我最初想象的要棘手。尽管如此,这是可能的,但它确实涉及相当多的代码。为了能够定位对象的实际Opacity属性Background Brush,您需要使用StoryBoard... 这就是此代码示例如此冗长的原因。
因为我们需要在 中使用一个Storyboard对象DataTrigger,这意味着我们必须使用 ,DataTrigger.EnterActions因为 aStoryboard不能在普通DataTrigger.Setters集合中使用。这意味着我们还必须使用DataTrigger.ExitActions来提供另一个Storyboard将Opacity属性设置回其原始值的方法。尝试这个:
<Grid Name="YourGrid">
<Grid.Background>
<SolidColorBrush Color="Green" Opacity="0.2" />
</Grid.Background>
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, ElementName=YourGrid}"
Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="Background.(SolidColorBrush.Opacity)">
<LinearDoubleKeyFrame Value="0.7" KeyTime="0:0:0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="Background.(SolidColorBrush.Opacity)">
<LinearDoubleKeyFrame Value="0.2" KeyTime="0:0:0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>
Run Code Online (Sandbox Code Playgroud)
尽管实现此方法需要大量代码,但它确实可以满足您的需求。但是,有一种更简单的方法可以获得相同的整体效果,但代码略少。您可以简单地Rectangle在每个Grid单元格或分区的背面添加一个,并在其上设置颜色和不透明度。使用这种方法,您可以简单地直接设置Rectangle.Opacity值,尽管您会使用额外的控件……选择权在您手中。