在WPF中,XAML是否能够获取当前渲染背景的颜色?

4

我有一个控件显示进度条。

我希望进度条的颜色能够有效地成为当前背景颜色的加强版,例如:

  • 如果背景是浅黄色,我想让进度条变成深黄色。
  • 如果背景是浅绿色,我想让进度条变成深绿色。
  • 等等。

在WPF中是否有可能实现这一点?

请注意,我不知道谁为我设置了背景颜色,因此无法手动设置它。

更新

我应该澄清一下,有些父控件在XAML中将Background设置为transparent

但是,在视觉树中,这仅意味着Background会传递给所有子元素。


1
你不能直接绑定到当前控件模板的背景吗? - Patrick Hofman
1
添加一个依附属性,该属性遍历 VisualTree 以获取父元素的背景色,怎么样? - Ignacio Soler Garcia
尝试使用父窗口的背景 ((Window)this.Parent).Background - Vaibhav
你是否正在尝试实现“主题”?采用这种方法(具有不同的样式/画笔等),您不需要在视图或ViewModel(mvvm?)中执行任何操作,而是通过使用相同的键来自动完成,但合并不同的“ResourceDisctionary”。 - Sinatr
@Simplyvaibh 谢谢你的建议,但是我正在使用MVVM,所以避免使用代码后台。 - Contango
2个回答

3
如果您知道控件类型,可以使用RelativeSource将背景绑定到它。然后根据检索到的Brush调整其以满足您的需求。 第一种方法如下所示,使用Converter:
 class BackgroundConverter : IValueConverter
 {
     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
     {
         var background = value as SolidColorBrush;
         if (background.Color == Colors.LightYellow) return new SolidColorBrush(Colors.Yellow);
         if (background.Color == Colors.LightGreen) return new SolidColorBrush(Colors.Green);
         return new SolidColorBrush(Colors.White);
     }

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
     {
         throw new NotImplementedException();
     }
}

XAML:

<Window.Resources>
    <local:BackgroundConverter x:Key="BackgroundConverter"/>
</Window.Resources>

<ProgressBar Background="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Background,
      Converter={StaticResource BackgroundConverter}}"/>

或者采用后一种方式只使用XAML:

<ProgressBar>
    <ProgressBar.Style>
        <Style TargetType="ProgressBar">
            <Setter Property="Background" Value="White"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Background}" Value="LightYellow">
                    <Setter Property="Background" Value="Yellow"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Background}" Value="LightGreen">
                    <Setter Property="Background" Value="Green"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ProgressBar.Style>
</ProgressBar>

1
这还不是全部。使用此绑定,ProgreeBar 的背景将与背景颜色相同。我认为他需要提供一个转换器,根据呈现的背景颜色调整颜色。 - Tomtom
感谢您的精彩回答,这非常有效。 - Contango

1
您可以按照以下常规样式使用进度条,并将前景色绑定到适当的ViewModel。 vm:ProgressBar是一个用户控件。
 <vm:ProgressBar x:Name="ProgressBar"
                                        Grid.RowSpan="3"
                                        Width="140"
                                        Height="120"
                                        Margin="12"
                                        Panel.ZIndex="5"
                                        Padding="10"
                                       DataContext.ProgressBarVisibility,
                                                             RelativeSource={RelativeSource AncestorType=Window,
                                                                                            AncestorLevel=1}}"
                                        d:DesignerVisibility="False">
                            <vm:ProgressBar.Foreground>
                                <RadialGradientBrush Center="0.5,0.5" GradientOrigin="0.4,0.4" RadiusX="0.5" RadiusY="0.5">
                                    <RadialGradientBrush.GradientStops>
                                        <GradientStop Offset="0" Color="Transparent" />
                                        <GradientStop Offset="1" Color="{Binding Path=FColor}" />
                                    </RadialGradientBrush.GradientStops>
                                </RadialGradientBrush>
                            </vm:ProgressBar.Foreground>
                        </vm:ProgressBar>

感谢您提供的出色答案。我特别喜欢了解到可以使用 d:DesignerVisibility="False" - Contango

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接