浏览代码

Add and implement IsHostedInColorPicker property to ColorView

This works-around some lifecycle issues by allowing the ColorView to specially handle how it handles property changes based on whether or not it is within a ColorPicker.
robloo 3 年之前
父节点
当前提交
2575a10fb0

+ 0 - 3
src/Avalonia.Controls.ColorPicker/ColorPicker/ColorPicker.cs

@@ -11,9 +11,6 @@
         /// </summary>
         public ColorPicker() : base()
         {
-            // Completely ignore property changes here
-            // The ColorView in the control template is responsible to manage this
-            base.ignorePropertyChanged = true;
         }
     }
 }

+ 24 - 0
src/Avalonia.Controls.ColorPicker/ColorView/ColorView.Properties.cs

@@ -148,6 +148,14 @@ namespace Avalonia.Controls
                 nameof(IsHexInputVisible),
                 true);
 
+        /// <summary>
+        /// Defines the <see cref="IsHostedInColorPicker"/> property.
+        /// </summary>
+        public static readonly StyledProperty<bool> IsHostedInColorPickerProperty =
+            AvaloniaProperty.Register<ColorView, bool>(
+                nameof(IsHostedInColorPicker),
+                false);
+
         /// <summary>
         /// Defines the <see cref="MaxHue"/> property.
         /// </summary>
@@ -395,6 +403,22 @@ namespace Avalonia.Controls
             set => SetValue(IsHexInputVisibleProperty, value);
         }
 
+        /// <summary>
+        /// Gets or sets a value indicating whether this <see cref="ColorView"/> is hosted
+        /// inside a <see cref="ColorPicker"/>'s control template.
+        /// </summary>
+        /// <remarks>
+        /// This is a special property to change how the <see cref="ColorView"/> internally
+        /// processes property updates. When a <see cref="ColorView"/> is hosted within a
+        /// <see cref="ColorPicker"/>, it does not need to handle most property changes.
+        /// Instead, the primary calculations are done within the <see cref="ColorPicker"/> itself.
+        /// </remarks>
+        public bool IsHostedInColorPicker
+        {
+            get => GetValue(IsHostedInColorPickerProperty);
+            set => SetValue(IsHostedInColorPickerProperty, value);
+        }
+
         /// <inheritdoc cref="ColorSpectrum.MaxHue"/>
         public int MaxHue
         {

+ 20 - 0
src/Avalonia.Controls.ColorPicker/ColorView/ColorView.cs

@@ -206,6 +206,26 @@ namespace Avalonia.Controls
                 return;
             }
 
+            // Special handling for when hosted within a ColorPicker and the ColorPicker is
+            // responsible for most of the internal processing and property updates.
+            if (IsHostedInColorPicker)
+            {
+                if (change.Property == ColorProperty ||
+                    change.Property == HsvColorProperty)
+                {
+                    ignorePropertyChanged = true;
+
+                    // The Hex text isn't currently bound with the ColorPicker and therefore
+                    // must still be updated here.
+                    SetColorToHexTextBox();
+
+                    ignorePropertyChanged = false;
+                }
+
+                base.OnPropertyChanged(change);
+                return;
+            }
+
             // Always keep the two color properties in sync
             if (change.Property == ColorProperty)
             {

+ 4 - 0
src/Avalonia.Controls.ColorPicker/Themes/Fluent/ColorPicker.xaml

@@ -43,7 +43,11 @@
           </DropDownButton.Content>
           <DropDownButton.Flyout>
             <Flyout FlyoutPresenterClasses="nopadding">
+              <!-- Note that IsHostedInColorPicker should always be set first.
+                   This tells the ColorView to avoid some internal processing that may
+                   conflict with the ColorPicker that is now the primary control. -->
               <ColorView x:Name="FlyoutColorView"
+                         IsHostedInColorPicker="True"
                          Color="{Binding Color, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
                          ColorModel="{Binding ColorModel, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
                          ColorSpectrumComponents="{TemplateBinding ColorSpectrumComponents}"