自定义ColorPicker2类
ColorPicker2.cs代码
using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Metadata; using Avalonia.Controls.Primitives; using Avalonia.Media; using System; namespace AvaloniaUI { [TemplatePart("PART_RedSlider", typeof(Slider))] [TemplatePart("PART_GreenSlider", typeof(Slider))] [TemplatePart("PART_BlueSlider", typeof(Slider))] public class ColorPicker2 : TemplatedControl { public static readonly StyledProperty<Color> ColorProperty = AvaloniaProperty.Register<ColorPicker, Color>(nameof(Color), Colors.Black); public static readonly StyledProperty<double> RedProperty = AvaloniaProperty.Register<ColorPicker, double>(nameof(Red), 0); public static readonly StyledProperty<double> GreenProperty = AvaloniaProperty.Register<ColorPicker, double>(nameof(Green), 0); public static readonly StyledProperty<double> BlueProperty = AvaloniaProperty.Register<ColorPicker, double>(nameof(Blue), 0); private Slider? redSlider; private Slider? greenSlider; private Slider? blueSlider; private IDisposable? colorSubscription; private IDisposable? redSubscription; private IDisposable? greenSubscription; private IDisposable? blueSubscription; public ColorPicker2() { // 当 Color 变化 → 更新 RGB colorSubscription = this.GetObservable(ColorProperty) .Subscribe(OnColorChanged); // 当任意 RGB 变化 → 更新 Color redSubscription = this.GetObservable(RedProperty) .Subscribe(_ => UpdateColorFromRgb()); greenSubscription = this.GetObservable(GreenProperty) .Subscribe(_ => UpdateColorFromRgb()); blueSubscription = this.GetObservable(BlueProperty) .Subscribe(_ => UpdateColorFromRgb()); } public Color Color { get => GetValue(ColorProperty); set => SetValue(ColorProperty, value); } public double Red { get => GetValue(RedProperty); set => SetValue(RedProperty, value); } public double Green { get => GetValue(GreenProperty); set => SetValue(GreenProperty, value); } public double Blue { get => GetValue(BlueProperty); set => SetValue(BlueProperty, value); } private void OnColorChanged(Color color) { // 更新 RGB Red = (double)color.R; Green = (double)color.G; Blue = (double)color.B; } private void UpdateColorFromRgb() { var newColor = Color.FromRgb((byte)Red, (byte)Green, (byte)Blue); if (newColor != Color) Color = newColor; } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); redSlider = e.NameScope.Find<Slider>("PART_RedSlider"); greenSlider = e.NameScope.Find<Slider>("PART_GreenSlider"); blueSlider = e.NameScope.Find<Slider>("PART_BlueSlider"); if (redSlider != null) redSlider[!!Slider.ValueProperty] = this[!!RedProperty]; if (greenSlider != null) greenSlider[!!Slider.ValueProperty] = this[!!GreenProperty]; if (blueSlider != null) blueSlider[!!Slider.ValueProperty] = this[!!BlueProperty]; } protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) { base.OnDetachedFromVisualTree(e); colorSubscription?.Dispose(); redSubscription?.Dispose(); greenSubscription?.Dispose(); blueSubscription?.Dispose(); } } }
ColorPicker.axaml代码
<Styles xmlns="https://github.com/avaloniaui" xmlns:local="using:AvaloniaUI" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Design.PreviewWith> </Design.PreviewWith> <!-- Add Styles Here --> <Style Selector="local|ColorPicker2"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> <Grid ColumnDefinitions="*,auto" RowDefinitions="auto,auto,auto" ColumnSpacing="8" RowSpacing="4"> <Slider Name="PART_RedSlider" Minimum="0" Maximum="255" Foreground="Red" Background="#22FF0000" VerticalAlignment="Center"> <Slider.Resources> <SolidColorBrush x:Key="SliderThumbBackground" Color="Red"/> </Slider.Resources> </Slider> <Slider Name="PART_GreenSlider" Grid.Row="1" Minimum="0" Maximum="255" Foreground="LimeGreen" Background="#2200FF00" VerticalAlignment="Center"> <Slider.Resources> <SolidColorBrush x:Key="SliderThumbBackground" Color="LimeGreen"/> </Slider.Resources> </Slider> <Slider Name="PART_BlueSlider" Grid.Row="2" Minimum="0" Maximum="255" Foreground="DodgerBlue" Background="#220000FF" VerticalAlignment="Center"> <Slider.Resources> <SolidColorBrush x:Key="SliderThumbBackground" Color="DodgerBlue"/> </Slider.Resources> </Slider> <Border Grid.Column="1" Grid.RowSpan="3" Width="50" Height="50" BorderBrush="Black" BorderThickness="1" CornerRadius="4" Margin="4,0,0,0"> <Border.Background> <SolidColorBrush Color="{Binding Color, RelativeSource={RelativeSource TemplatedParent}}"/> </Border.Background> </Border> </Grid> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </Styles>
ColorPickerUserControlTest.axaml代码
<Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Width="300" Height="300" xmlns:local="using:AvaloniaUI" x:Class="AvaloniaUI.ColorPickerUserControlTest" Title="ColorPickerUserControlTest"> <StackPanel> <local:ColorPicker2 x:Name="colorPicker" Margin="2" Padding="3" Color="Beige"> </local:ColorPicker2> <Button x:Name="cmdGet" HorizontalAlignment="Center" Margin="5,20,5,0" Padding="2" Click="cmdGet_Click">Get Color</Button> <Button x:Name="cmdSet" HorizontalAlignment="Center" Margin="5,0,5,0" Padding="2" Click="cmdSet_Click">Reset Color</Button> <Button Margin="5,0,5,0" Padding="2" HorizontalAlignment="Center" Click="cmdUndo_Click">Undo</Button> <TextBlock x:Name="lblColor" Margin="10" HorizontalAlignment="Center"/> </StackPanel> </Window>
ColorPickerUserControlTest.cs代码
using Avalonia;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Media;
using Shares.Avalonia;
namespace AvaloniaUI;
public partial class ColorPickerUserControlTest : Window
{
private readonly UndoRedoManager undoManager = new();
public ColorPickerUserControlTest()
{
InitializeComponent();
this.Load("avares://AvaloniaUI/Demos/Book/18/CustomControls/ColorPicker.axaml");//这个是在我的扩展里实现了,以后不再重复这些自定义的函数了。
undoManager.Attach(colorPicker, ColorPicker2.ColorProperty);//这个是在之前的RedoUndo例子里
}
// 点击“Get Color”按钮
private void cmdGet_Click(object? sender, RoutedEventArgs e)
{
if (colorPicker != null)
{
var color = colorPicker.Color;
// Avalonia 中没有 WPF 的 MessageBox,可用自定义对话框或简单显示文本:
lblColor.Text = $"当前颜色:{color}";
}
}
// 点击“Reset Color”按钮
private void cmdSet_Click(object? sender, RoutedEventArgs e)
{
if (colorPicker != null)
{
colorPicker.Color = Colors.Beige;
}
}
// 响应 ColorChanged 事件
private void colorPicker_ColorChanged(object? sender, ColorChangedEventArgs e)
{
if (lblColor != null)
{
lblColor.Text = $"颜色变为:{e.NewColor}";
}
}
private void cmdUndo_Click(object? sender, RoutedEventArgs e)
{
undoManager.Undo(colorPicker);
}
}
运行效果

浙公网安备 33010602011771号