I'm trying to make some basic color picker functionality. I have form with Image holding DrawingImage as source from which I am getting brushes to edit them.
There is a rectangle to show redacted color, textbox for color's hex value and sliders for rgb values, all of which bound to custom dependency property (ActiveBrush) that holds selected brush for editing.
Important bits:
//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>
Basically, when I change whole color (as with textbox hex string), it works as intended. But changing individual color properties (r, g, b - they are not dependency properties) with sliders is not reflected visually on screen, although when I look in debugger, they are correctly changing ActiveBrush's color value, so binding works.
I've managed it to work with Rectangle by calling InvalidateVisual on it in Slider's OnValueChanged event, but it didn't work for Image. Also, calling InvalidateProperty on my ActiveBrush dependency property, did not have any perceived effect.
You have correctly identified the cause of the problem: since R, G, B are not dependency properties, so even when there value changes, other controls are unaware of it. So you need to implement those notifications yourself. There are several ways to do this:
Option a) Create separate
DependencyPropertyfor each color component (R,G,B), and in thePropertyChangedcallback for those properties update theActiveBrush.In the
OnPropertyChangedcallback for theActiveBrushPropertydo the opposite - update all color component properties.Btw., you should not register Dependency Properties on
FrameworkElement, use the type of your class in which the property is declared.Option b) Use ViewModel with
INotifyPropertyChangedOption c) Implement IValueConverter to convert Brush to a single component and back, and use it in the bindings to Slider.