diff --git a/src/Avalonia.Controls.ColorPicker/ColorPicker/ColorPicker.cs b/src/Avalonia.Controls.ColorPicker/ColorPicker/ColorPicker.cs
index 39369bcbdb..29f9f3c571 100644
--- a/src/Avalonia.Controls.ColorPicker/ColorPicker/ColorPicker.cs
+++ b/src/Avalonia.Controls.ColorPicker/ColorPicker/ColorPicker.cs
@@ -1,4 +1,6 @@
-namespace Avalonia.Controls
+using Avalonia.Controls.Primitives;
+
+namespace Avalonia.Controls
{
///
/// Presents a color for user editing using a spectrum, palette and component sliders within a drop down.
@@ -11,8 +13,33 @@
///
public ColorPicker() : base()
{
- // Completely ignore property changes here
- // The ColorView in the control template is responsible to manage this
+ }
+
+ ///
+ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+ {
+ base.OnApplyTemplate(e);
+
+ // Until this point the ColorPicker itself is responsible to process property updates.
+ // This, for example, syncs Color with HsvColor and updates primitive controls.
+ //
+ // However, when the template is created, hand-off this change processing to the
+ // ColorView within the control template itself. Remember ColorPicker derives from
+ // ColorView so we don't want two instances of the same logic fighting each other.
+ // It is best to hand-off to the ColorView in the control template because that is the
+ // primary point of user-interaction for the overall control. It also simplifies binding.
+ //
+ // Keep in mind this hand-off is not possible until the template controls are created
+ // which is done after the ColorPicker is instantiated. The ColorPicker must still
+ // process updates before the template is applied to ensure all property changes in
+ // XAML or object initializers are handled correctly. Otherwise, there can be bugs
+ // such as setting the Color property doesn't work because the HsvColor is never updated
+ // and then the Color value is lost once the template loads (and the template ColorView
+ // takes over).
+ //
+ // In order to complete this hand-off, completely ignore property changes here in the
+ // ColorPicker. This means the ColorView in the control template is now responsible to
+ // process property changes and handle primary calculations.
base.ignorePropertyChanged = true;
}
}