I have a ContentDialog
with a few controls, one of them a color picker, where the user can pick a color.
When the dialog loads I want to initialize the color picker with a given color (from a previous selection), there is also a rectangle control which shows the selected color.
The color picker is bound to a property in the view model (TwoWay) and the rectangle background color is also bound (OneWay) to the same property.
<Viewbox Margin="5" MaxWidth="100" Stretch="Fill">
<ColorPicker x:Name="fontColorPicker"
ColorSpectrumShape="Ring"
IsColorPreviewVisible="False"
IsColorChannelTextInputVisible="False"
IsHexInputVisible="False" Color="{x:Bind ViewModel.SelectedColor, Mode=TwoWay}" ColorChanged="fontColorPicker_ColorChanged" />
</Viewbox>
<Rectangle Height="50" Width="50" Margin="10,0,0,0" StrokeThickness="1" Stroke="DarkGray">
<Rectangle.Fill>
<SolidColorBrush Color="{x:Bind ViewModel.SelectedColor, Mode=OneWay}"/>
</Rectangle.Fill>
</Rectangle>
All is fine until I want to set the initial color for the color picker. As Color is a struct, I cannot change the A, R, G, B properties, I have to instanciate a new struct and assign it to the property. But with this assignment the binding will get removed.
This is how I currently change the value in the view model, to initialize the value (settings.Color is not a Windows.UI.Color, but a class from another imaging library, so I have to convert the values):
// Font color
if (settings.Color != null)
{
var pickerColor = new Windows.UI.Color
{
A = settings.Color.A,
R = settings.Color.R,
G = settings.Color.G,
B = settings.Color.B
};
ViewModel.SelectedColor = pickerColor;
}
I know, I could re-create the binding after this so make it work again, but I am sure there must be a more clean approach without the need for this to happen.
You can make the ViewModel class implement the INotifyPropertyChanged
interface:
public class ViewModel : INotifyPropertyChanged
{
private Color _selectedColor;
public Color SelectedColor
{
get => _selectedColor;
set
{
_selectedColor = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
In this way, when you bind SelectedColor
through OneWay, changes to SelectedColor
will notify the UI to also change.