wpf 绑定颜色属性

czq61nw1  于 2023-03-19  发布在  其他
关注(0)|答案(1)|浏览(218)

我正在尝试做一些基本的颜色选择器功能。我有一个带有图像的窗体,它保存了DrawingImage作为源代码,我可以从中获得画笔来编辑它们。
有一个矩形显示密文颜色,文本框颜色的十六进制值和滑块的rgb值,所有这些都绑定到自定义依赖属性(ActiveBrush),保持选定的画笔编辑。
重要信息:

//ActiveBrush
public static DependencyProperty ActiveBrushProperty = DependencyProperty.Register("ActiveBrush", typeof(SolidColorBrush), typeof(FrameworkElement)); 

//XAML
<StackPanel DataContext ="{Binding ElementName = window, Path = ActiveBrush}">
    <Rectangle >
        <Rectangle.Fill>
            <SolidColorBrush Color="{Binding Path=Color, Mode="TwoWay", UpdateSourceTrigger="PropertyChanged"}"/>
        </Rectangle.Fill>
    </Rectangle>

    <TextBox Text = "{Binding Path=Color, Mode="TwoWay", UpdateSourceTrigger="PropertyChanged"}" />

    <Slider Value = "{Binding Path=Color.R, Mode="TwoWay", UpdateSourceTrigger="PropertyChanged"}" />
</StackPanel>

基本上,当我改变整个颜色(如文本框十六进制字符串)时,它会按预期工作。但是用滑块改变单个颜色属性(r,g,b -它们不是依赖属性)并不会在屏幕上直观地反映出来,尽管当我在调试器中查看时,它们正确地改变了ActiveBrush的颜色值,所以绑定工作正常。
我在Slider的OnValueChanged事件中对Rectangle调用InvalidateVisual,使它可以与Rectangle一起使用,但对Image不起作用。另外,对ActiveBrush依赖属性调用InvalidateProperty,也没有任何效果。

w80xi6nr

w80xi6nr1#

您已正确识别问题的原因:因为R,G,B不是依赖属性,所以即使它们的值改变了,其他控件也不知道。2所以你需要自己实现这些通知。3有几种方法可以做到这一点:

**选项a)**为每个颜色分量(R、G、B)创建单独的DependencyProperty,并在这些属性的PropertyChanged回调中更新ActiveBrush

public static DependencyProperty RComponentProperty = DependencyProperty.Register("RComponent", typeof(byte), typeof(YorWindow), new PropertyMetadata(0, OnColorComponentChanged)); 
   public static DependencyProperty GComponentProperty = DependencyProperty.Register("GComponent", typeof(byte), typeof(YorWindow), new PropertyMetadata(0, OnColorComponentChanged)); 
   public static DependencyProperty bComponentProperty = DependencyProperty.Register("BComponent", typeof(byte), typeof(YorWindow), new PropertyMetadata(0, OnColorComponentChanged)); 
   private static void OnColorComponentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   {
        YorWindow @this = (YorWindow)d;
        Color activeColor = Color.FromRGB(@this.RComponent, @this.GComponent, @this.BComponent);
        d.SetCurrentValue(ActiveBrushProperty, new SolidColorBrush(activeColor));
   }

ActiveBrushPropertyOnPropertyChanged回调中执行相反的操作-更新所有颜色组件属性。
顺便说一句,你不应该在FrameworkElement上注册依赖属性,使用你的类的类型来声明属性。

class YourClass
{
    public static DependencyProperty ActiveBrushProperty = DependencyProperty.Register("ActiveBrush", typeof(SolidColorBrush), typeof(YourClass)); 
}

**选项B)**使用带有INotifyPropertyChanged的视图模型

public byte RComponent 
{
   get => ActiveBrush.Color.R;
   set 
   {
      if(value != ActiveBrush.Color.R)
      {
          ActiveBrush.Color.R = value;
          RaisePropertyChanged(nameof(RComponent));
          RaisePropertyChanged(nameof(ActiveBrush));
      }
   }
}

**选项c)**实现IValueConverter以将Brush转换为单个组件,并在绑定到Slider时使用它。

相关问题