通过xaml来定义Template样式。
ColorPicker.cs代码
using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Metadata; using Avalonia.Controls.Primitives; using Avalonia.Media; using System; namespace Shares.Avalonia.CustomControls; [TemplatePart("PART_RedSlider", typeof(Slider))] [TemplatePart("PART_GreenSlider", typeof(Slider))] [TemplatePart("PART_BlueSlider", typeof(Slider))] public class ColorPicker : 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 ColorPicker() { // 当 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(); } }
ColorPickerTwoWays.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" Height="350" Width="300" xmlns:local="using:AvaloniaUI" x:Class="AvaloniaUI.ColorPickerTwoWays" Title="ColorPickerTwoWays"> <Window.Resources> <ControlTemplate x:Key="FancyColorPickerTemplate" TargetType="local:ColorPicker2"> <Border Background="LightGoldenrodYellow" BorderBrush="Black" BorderThickness="1" Padding="8"> <Grid RowDefinitions="*,auto" ColumnDefinitions="*,auto,auto,auto"> <!-- 通用样式 --> <Grid.Styles> <Style Selector="Slider"> <Setter Property="Orientation" Value="Vertical"/> <Setter Property="TickFrequency" Value="10"/> <Setter Property="Minimum" Value="0"/> <Setter Property="Maximum" Value="255"/> <Setter Property="Margin" Value="5"/> </Style> <Style Selector="TextBlock"> <Setter Property="Margin" Value="3"/> <Setter Property="FontSize" Value="10"/> <Setter Property="HorizontalAlignment" Value="Center"/> </Style> </Grid.Styles> <!-- 圆形颜色显示 --> <Ellipse Grid.Column="0" Grid.RowSpan="2" Margin="10" Stroke="LightGray" StrokeThickness="5" Height="120"> <Ellipse.Fill> <SolidColorBrush Color="{Binding Color, RelativeSource={RelativeSource TemplatedParent}}"/> </Ellipse.Fill> </Ellipse> <!-- 三个滑块 --> <Slider x:Name="PART_RedSlider" Grid.Column="1"/> <TextBlock Grid.Row="1" Grid.Column="1" Text="RED"/> <Slider x:Name="PART_GreenSlider" Grid.Column="2"/> <TextBlock Grid.Row="1" Grid.Column="2" Text="GREEN"/> <Slider x:Name="PART_BlueSlider" Grid.Column="3"/> <TextBlock Grid.Row="1" Grid.Column="3" Text="BLUE"/> </Grid> </Border> </ControlTemplate> </Window.Resources> <StackPanel> <!-- 第一个颜色选择器 --> <local:ColorPicker2 x:Name="colorPicker1" Margin="2" Padding="3" Color="AliceBlue"/> <!-- 第二个颜色选择器使用 Fancy 模板,并与第一个双向绑定 --> <local:ColorPicker2 x:Name="colorPicker2" Margin="5,20,5,5" Template="{StaticResource FancyColorPickerTemplate}" Color="{Binding #colorPicker1.Color, Mode=TwoWay}"/> </StackPanel> </Window>
ColorPickerTwoWays.axaml.cs代码
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Shares.Avalonia;
namespace AvaloniaUI;
public partial class ColorPickerTwoWays : Window
{
public ColorPickerTwoWays()
{
InitializeComponent();
this.Load("avares://AvaloniaUI/Demos/Book/18/CustomControls/ColorPicker.axaml");
}
}
运行效果

浙公网安备 33010602011771号