【问题标题】:how to control opacity of descendant controls based on parent control's opacity ?如何根据父控件的不透明度控制后代控件的不透明度?
【发布时间】:2014-02-26 17:15:06
【问题描述】:

我创建了一个用户控件,其中包含网格和网格内的几个控件。我已将父网格的不透明度设置为 .1,并且我想将后代控件的不透明度设置为 1。在 XAML 树体系结构中可以这样做吗? 这是我的 xaml 代码:

<Grid Name="busyIndicatorGrid" Visibility="Visible" Opacity=".2"
      Background="DarkBlue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    <StackPanel Orientation="Vertical" Opacity="1" 
                Background="Transparent" HorizontalAlignment="Center" VerticalAlignment="Center">
        <ProgressBar Name="progressBar" Foreground="White" 
                     IsIndeterminate="True" MinWidth="100" Height="25" VerticalAlignment="Center"/>
        <TextBlock Name="txtProgressText" 
                   FontSize="40" 
                   Margin="0,5,0,0" 
                   Text="Please wait while application is being initialized."
                   TextAlignment="Left" TextWrapping="Wrap" />
    </StackPanel>
</Grid>

【问题讨论】:

    标签: wpf xaml opacity


    【解决方案1】:

    不透明度是一个将沿子树传播的属性。

    如果父级不透明度为 0.5,子级不透明度为 0.2,则父级将使用 50% 绘制,子级将使用父级 50% 的 20% 绘制...有点类似只是为了更好地理解...我希望你找我:)

    试试这个,你会看到:

    <Grid Name="busyIndicatorGrid" Visibility="Visible" Opacity=".2">
         <StackPanel Orientation="Vertical" Opacity="1" >
         ...
    
    <Grid Name="busyIndicatorGrid" Visibility="Visible" Opacity=".2">
         <StackPanel Orientation="Vertical" Opacity="0.5">
        ...
    

    这两个的绘制方式不同,这意味着子级不会从其父级获取不透明度值,而是计算自己的值。

    如果您想控制内部子项的绘制方式,我建议您创建一个附加属性,该属性沿 VisualTree 继承其内容,当设置为 true 时,它​​将其“底层”关联元素的不透明度更改为1 或之前的旧值。

    这是一个例子:

        public static bool GetChangeOpacity(DependencyObject obj)
        {
            return (bool)obj.GetValue(ChangeOpacityProperty);
        }
    
        public static void SetChangeOpacity(DependencyObject obj, bool value)
        {
            obj.SetValue(ChangeOpacityProperty, value);
        }
    
        // Using a DependencyProperty as the backing store for ChangeOpacity.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ChangeOpacityProperty =
            DependencyProperty.RegisterAttached("ChangeOpacity", typeof(bool), typeof(YourClass), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits, PropertyChangedCallback));
    
        private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
        {
            FrameworkElement fe = dependencyObject as FrameworkElement;
            if (fe != null && (bool)args.NewValue)
            {
                fe.Tag = fe.Opacity;
                fe.Opacity = 1;
            }
            else if(fe != null && fe.Tag != null)
            {
                fe.Opacity = (double)fe.Tag;
            }
        }
    

    【讨论】:

    • 感谢您的解释 :) 您能否添加您解释的代码 sn-p ?
    • 我刚做了。看看吧。
    • 我尝试使用您所说的附加行为,但是当我的行为设置为 true 但问题仍然存在时,我没有看到任何变化,就像我将内部控件不透明度设置为 1 一样。父网格控件的不透明度设置为 .2,我希望在不应用任何不透明度的情况下看到内部控件完全可见。
    • 再读一遍如果父级不透明度为 0.5,子级不透明度为 0.2,则父级将使用 50% 绘制,子级将使用父级 50% 的 20% 绘制... 子级将始终在其绘制计算中采用父级不透明度。如果您想将颜色更改为不那么强烈但不能完全控制,您应该考虑更改颜色的不透明度。
    【解决方案2】:

    感谢大家的宝贵建议。但是我找到了通过使用画笔作为父网格控件来解决我的问题的方法。

    <Grid Name="busyIndicatorGrid" Visibility="Visible" Opacity=".2"
      HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <Grid.Background>
            <SolidColorBrush Color="DarkBlue" Opacity="0.2"/>
        </Grid.Background>
    <StackPanel Orientation="Vertical"
                Background="Transparent" HorizontalAlignment="Center" VerticalAlignment="Center">
        <ProgressBar Name="progressBar" Foreground="White" 
                     IsIndeterminate="True" MinWidth="100" Height="25" VerticalAlignment="Center"/>
        <TextBlock Name="txtProgressText" 
                   FontSize="40" 
                   Margin="0,5,0,0" 
                   Text="Please wait while application is being initialized."
                   TextAlignment="Left" TextWrapping="Wrap" />
    </StackPanel>
    

    通过这样做,它将使用我在背景属性中定义的不透明度绘制父网格,并且对内部控件没有影响。所有控件都将照常绘制,没有在父网格上设置的任何不透明度覆盖效果。

    【讨论】:

      猜你喜欢
      • 2012-03-28
      • 1970-01-01
      • 2011-08-31
      • 1970-01-01
      • 2011-02-08
      • 2011-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多