diff --git a/Microsoft.Toolkit.Uwp.UI.Controls.Input/ColorPicker/ColorPickerButton.cs b/Microsoft.Toolkit.Uwp.UI.Controls.Input/ColorPicker/ColorPickerButton.cs
index 34c90a5cb90..dc785d1fbba 100644
--- a/Microsoft.Toolkit.Uwp.UI.Controls.Input/ColorPicker/ColorPickerButton.cs
+++ b/Microsoft.Toolkit.Uwp.UI.Controls.Input/ColorPicker/ColorPickerButton.cs
@@ -81,7 +81,7 @@ public Color SelectedColor
/// Identifies the dependency property.
///
public static readonly DependencyProperty SelectedColorProperty =
- DependencyProperty.Register(nameof(SelectedColor), typeof(Color), typeof(ColorPickerButton), new PropertyMetadata(null));
+ DependencyProperty.Register(nameof(SelectedColor), typeof(Color), typeof(ColorPickerButton), new PropertyMetadata(null, new PropertyChangedCallback(SelectedColorChanged)));
#pragma warning disable SA1306 // Field names should begin with lower-case letter
//// Template Parts
@@ -142,6 +142,14 @@ protected override void OnApplyTemplate()
}
}
+ private static void SelectedColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ if (d is ColorPickerButton instance && !(instance.ColorPicker is null))
+ {
+ instance.ColorPicker.Color = instance.SelectedColor;
+ }
+ }
+
private void ColorPicker_ColorChanged(Microsoft.UI.Xaml.Controls.ColorPicker sender, Microsoft.UI.Xaml.Controls.ColorChangedEventArgs args)
{
SelectedColor = args.NewColor;
diff --git a/UITests/UITests.Tests.Shared/Controls/ColorPickerButtonTest.cs b/UITests/UITests.Tests.Shared/Controls/ColorPickerButtonTest.cs
new file mode 100644
index 00000000000..f1672919788
--- /dev/null
+++ b/UITests/UITests.Tests.Shared/Controls/ColorPickerButtonTest.cs
@@ -0,0 +1,85 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Windows.Apps.Test.Foundation.Controls;
+using Windows.UI.Xaml.Tests.MUXControls.InteractionTests.Common;
+using Windows.UI.Xaml.Tests.MUXControls.InteractionTests.Infra;
+
+#if USING_TAEF
+using WEX.Logging.Interop;
+using WEX.TestExecution;
+using WEX.TestExecution.Markup;
+#else
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+#endif
+
+namespace UITests.Tests
+{
+ [TestClass]
+ public class ColorPickerButtonTest : UITestBase
+ {
+ [ClassInitialize]
+ [TestProperty("RunAs", "User")]
+ [TestProperty("Classification", "ScenarioTestSuite")]
+ [TestProperty("Platform", "Any")]
+ public static void ClassInitialize(TestContext testContext)
+ {
+ TestEnvironment.Initialize(testContext, WinUICsUWPSampleApp);
+ }
+
+ ///
+ /// This test validates the two way binding of the selected color. It verifies that
+ /// when the bound property changes this change is properly forwarded to the internal colorpicker.
+ /// See also issue #4367
+ ///
+ [TestMethod]
+ [TestPage("ColorPickerButtonTestPage")]
+ public void TwoWayTestMethod()
+ {
+ var colorpicker = new Button(FindElement.ById("TheColorPickerButton"));
+
+ var redButton = new Button(FindElement.ById("SetRedButton"));
+
+ Verify.IsNotNull(colorpicker);
+ Verify.IsNotNull(redButton);
+
+ colorpicker.Click();
+
+ Wait.ForIdle();
+ var colorInput = GetColorPickerInputField();
+
+ Verify.AreEqual("008000", colorInput.GetText());
+
+ // close the picker
+ colorpicker.Click();
+
+ Wait.ForIdle();
+
+ redButton.Click();
+
+ Wait.ForIdle();
+
+ colorpicker.Click();
+
+ var colorInput_new = GetColorPickerInputField();
+ Verify.AreEqual("FF0000", colorInput_new.GetText());
+ }
+
+ private static Edit GetColorPickerInputField()
+ {
+ var channelButton = new Button(FindElement.ByName("Channels"));
+ Verify.IsNotNull(channelButton);
+
+ Wait.ForIdle();
+
+ channelButton.Click();
+
+ Wait.ForIdle();
+
+ var colorInput = new Edit(FindElement.ByName("Hexadecimal Color Input"));
+ Verify.IsNotNull(colorInput);
+ return colorInput;
+ }
+ }
+}
\ No newline at end of file
diff --git a/UITests/UITests.Tests.Shared/Controls/ColorPickerButtonTestPage.xaml b/UITests/UITests.Tests.Shared/Controls/ColorPickerButtonTestPage.xaml
new file mode 100644
index 00000000000..27f563c0bc4
--- /dev/null
+++ b/UITests/UITests.Tests.Shared/Controls/ColorPickerButtonTestPage.xaml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/UITests/UITests.Tests.Shared/Controls/ColorPickerButtonTestPage.xaml.cs b/UITests/UITests.Tests.Shared/Controls/ColorPickerButtonTestPage.xaml.cs
new file mode 100644
index 00000000000..503105e9603
--- /dev/null
+++ b/UITests/UITests.Tests.Shared/Controls/ColorPickerButtonTestPage.xaml.cs
@@ -0,0 +1,47 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.ComponentModel;
+using Windows.UI;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace UITests.App.Pages
+{
+ ///
+ /// An empty page that can be used on its own or navigated to within a Frame.
+ ///
+ public sealed partial class ColorPickerButtonTestPage : Page, INotifyPropertyChanged
+ {
+ private Color _theColor = Colors.Green;
+
+ public Color TheColor
+ {
+ get => _theColor;
+ set
+ {
+ if (_theColor != value)
+ {
+ _theColor = value;
+ OnPropertyChanged(nameof(TheColor));
+ }
+ }
+ }
+
+ public ColorPickerButtonTestPage()
+ {
+ DataContext = this;
+ this.InitializeComponent();
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ private void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+
+ private void Button_Click(object sender, RoutedEventArgs e)
+ {
+ TheColor = Colors.Red;
+ }
+ }
+}
\ No newline at end of file