【问题标题】:XAML to change background opacity without changing colorXAML 更改背景不透明度而不更改颜色
【发布时间】:2014-06-04 12:49:55
【问题描述】:

在我的 C# / WPF / .NET 4.5 应用程序中,我想实现一个 Trigger 来切换背景不透明度控制而不改变其颜色。

通常要设置控件的背景画笔,我会使用以下Setter

<Setter TargetName="TargetControl" Property="Background">
<Setter.Value>
  <SolidColorBrush Color="Red" Opacity="0.2"/>
</Setter.Value>

现在我只能更改不透明度而不是颜色。在这种情况下,我的 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>

【问题讨论】:

    标签: c# wpf xaml


    【解决方案1】:

    我花了一点时间才想出最好的方法来做到这一点......结果证明这比我最初想象的要复杂。尽管如此,这是可能的,但它确实涉及相当多的代码。为了能够定位Background Brush 对象的实际Opacity 属性,您需要使用StoryBoard...这就是此代码示例如此冗长的原因。

    因为我们需要在DataTrigger中使用Storyboard对象,这意味着我们必须使用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>
    

    尽管实现此方法需要大量代码,但它确实可以满足您的需求。但是,有一种更简单的方法可以获得相同的整体效果,但代码略少。您可以简单地将Rectangle 添加到每个Grid 单元格的后面,或者在其上设置颜色和不透明度。使用这种方法,您可以直接设置 Rectangle.Opacity 值,尽管您会使用额外的控件...选择权在您手中。

    【讨论】:

    • 我最终使用了Rectangle 方法=)
    【解决方案2】:

    这个答案与@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>
    

    【讨论】:

    • +1 如果只是为了“总是太多”注释。但也因为它值得认可。
    【解决方案3】:

    “网格”有自己的“不透明度”属性和“背景”属性。也许使用您的触发器来更改不透明度并单独保留背景颜色?

    【讨论】:

    • -1 更改Grid.Opacity 显然会使所有内容都看穿......显然不是所要求的。
    • “GridWithin”是项目控件中单个项目的模板根。
    • 触发 AlternatingIndex 以设置该网格的背景并触发 IsHIt 以设置其不透明度
    • “GridWithin”是项目控件中单个项目的模板的根...首先,是什么让您这么认为?它肯定没有显示在问题作者的 XAML 中。其次,即使它确实只包含一个控件并且您设置了Grid.Opacity 属性,单个控件也会淡出,我很确定这不是要求。
    • 首先,“GridWithin”是 ItemsControl 的 ItemTemplate 的 DataTemplate 的根,所以这确实使它成为单个 itm 的“根”
    猜你喜欢
    • 2012-09-20
    • 2019-08-14
    • 2014-07-12
    • 1970-01-01
    • 2016-01-15
    • 1970-01-01
    • 2013-03-04
    • 2012-09-18
    • 1970-01-01
    相关资源
    最近更新 更多