wpf XAML 在不改变颜色的情况下改变背景不透明度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24037938/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
XAML to change background opacity without changing color
提问by mbaytas
In my C#/ WPF/ .NET 4.5app I would like to implement a Triggerthat toggles the background opacity of a control without changing its color.
在我的C#/ WPF/ .NET 4.5应用程序中,我想实现一个Trigger在不更改控件颜色的情况下切换控件的背景不透明度。
Normally to set the background brush of a control, I would use the following Setter:
通常要设置控件的背景画笔,我会使用以下内容Setter:
<Setter TargetName="TargetControl" Property="Background">
<Setter.Value>
<SolidColorBrush Color="Red" Opacity="0.2"/>
</Setter.Value>
Now I am in a situation where I have to change the opacity only and not the color. What would my setter look like in this case, where I don't care what color the background is but I want to preserve the color while changing the opacity?
现在我处于一种情况,我只需要改变不透明度而不是颜色。在这种情况下,我的 setter 会是什么样子,我不在乎背景是什么颜色,但我想在更改不透明度的同时保留颜色?
More details:
更多细节:
The reason for this is that I am working on an ItemsControlwhere the background color changes depending on the item's AlternationIndex:
这样做的原因是我正在研究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>
采纳答案by Sheridan
It took me a little while to think of the best way to do this... it turns out that it was trickier than I had first thought. All the same, it is possible, but it does involve quite a lot of code. In order to be able to target the actual Opacityproperty of the Background Brushobject, you'll need to use a StoryBoard... that's why this code example is so verbose.
我花了一点时间才想到这样做的最佳方法……结果证明这比我最初想象的要棘手。尽管如此,这是可能的,但它确实涉及相当多的代码。为了能够定位对象的实际Opacity属性Background Brush,您需要使用StoryBoard... 这就是此代码示例如此冗长的原因。
Because we need to use a Storyboardobject in the DataTrigger, that means that we must use the DataTrigger.EnterActionsas a Storyboardcannot be used in the normal DataTrigger.Setterscollection. This follows that we must also use the DataTrigger.ExitActionsto provide another Storyboardthat sets the Opacityproperty back to its original value. Try this:
因为我们需要在 中使用一个Storyboard对象DataTrigger,这意味着我们必须使用 来DataTrigger.EnterActions作为一个Storyboard不能在普通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>
Despite the amount of code required to implement this method, it does do exactly what you were after. However, there is a simpler way to get the same overall effect, but with slightly less code. You couldsimply add a Rectangleinto the back of each Gridcell, or division and set the colours and opacity on that instead. Using this method, you could simply set the Rectangle.Opacityvalue directly, although you would be using extra controls... the choice is yours.
尽管实现此方法需要大量代码,但它确实可以满足您的需求。但是,有一种更简单的方法可以获得相同的整体效果,但代码略少。您可以简单地Rectangle在每个Grid单元格或分区的背面添加一个,并在其上设置颜色和不透明度。使用这种方法,您可以简单地直接设置Rectangle.Opacity值,尽管您将使用额外的控件……选择权在您手中。
回答by Reinstate Monica
This answer is almost identical to @Sheridans, but it saves a few lines of XAML (and the are always too many as it is...)
这个答案几乎与@Sheridans 相同,但它节省了几行 XAML(而且总是太多……)
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 Storyboard.TargetProperty="Background.(SolidColorBrush.Opacity)">
<DoubleAnimation To="0.7" Duration="0" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard Storyboard.TargetProperty="Background.(SolidColorBrush.Opacity)">
<DoubleAnimation To="0.2" Duration="0" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>
回答by Dave
"Grid" has its own "Opacity" property as well as a "Background" property. Perhaps use your trigger to change that opacity and leave the background colour alone?
“Grid”有它自己的“Opacity”属性和“Background”属性。也许使用您的触发器来更改不透明度并单独保留背景颜色?

