1新建wpf项目
2新建wpf UserControl库
<UserControl x:Class="CustomControl.ColorPickerUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:CustomControl"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" x:Name="colorPicker">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Slider Name="sliderRed" Minimum="0" Maximum="255"
Margin="{Binding ElementName=colorPicker,Path=Padding}"
Value="{Binding ElementName=colorPicker,Path=Red}"></Slider>
<Slider Grid.Row="1" Name="sliderGreen" Minimum="0" Maximum="255"
Margin="{Binding ElementName=colorPicker,Path=Padding}"
Value="{Binding ElementName=colorPicker,Path=Green}"></Slider>
<Slider Grid.Row="2" Name="sliderBlue" Minimum="0" Maximum="255"
Margin="{Binding ElementName=colorPicker,Path=Padding}"
Value="{Binding ElementName=colorPicker,Path=Blue}"></Slider>
<Rectangle Grid.Column="1" Grid.RowSpan="3"
Margin="{Binding ElementName=colorPicker,Path=Padding}"
Width="50" Stroke="Black" StrokeThickness="1">
<Rectangle.Fill>
<SolidColorBrush Color="{Binding ElementName=colorPicker,Path=Color}"></SolidColorBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace CustomControl
{
/// <summary>
/// ColorPickerUserControl.xaml 的交互逻辑
/// </summary>
public partial class ColorPickerUserControl : UserControl
{
public ColorPickerUserControl()
{
InitializeComponent();
}
public Color Color
{
get { return (Color)GetValue(ColorProperty); }
set { SetValue(ColorProperty, value); }
}
public byte Red
{
get { return (byte)GetValue(RedProperty); }
set { SetValue(RedProperty, value); }
}
public byte Green
{
get { return (byte)GetValue(GreenProperty); }
set { SetValue(GreenProperty, value); }
}
public byte Blue
{
get { return (byte)GetValue(BlueProperty); }
set { SetValue(BlueProperty, value); }
}
public static readonly DependencyProperty ColorProperty =
DependencyProperty.Register("Color", typeof(Color), typeof(ColorPickerUserControl), new PropertyMetadata(Colors.Black,OnColorChanged));
public static readonly DependencyProperty RedProperty =
DependencyProperty.Register("Red", typeof(byte), typeof(ColorPickerUserControl), new PropertyMetadata(OnColorRGBChanged));
public static readonly DependencyProperty GreenProperty =
DependencyProperty.Register("Green", typeof(byte), typeof(ColorPickerUserControl), new PropertyMetadata(OnColorRGBChanged));
public static readonly DependencyProperty BlueProperty =
DependencyProperty.Register("Blue", typeof(byte), typeof(ColorPickerUserControl), new PropertyMetadata(OnColorRGBChanged));
private static void OnColorRGBChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ColorPickerUserControl uc = (ColorPickerUserControl)d;
Color color = uc.Color;
if (e.Property==RedProperty)
{
color.R = (byte)e.NewValue;
}
else if (e.Property==GreenProperty)
{
color.G = (byte)e.NewValue;
}
else if (e.Property == BlueProperty)
{
color.B = (byte)e.NewValue;
}
uc.Color = color;
}
private static void OnColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ColorPickerUserControl uc = (ColorPickerUserControl)d;
Color color = (Color)e.NewValue;
uc.Red = color.R;
uc.Green = color.G;
uc.Blue = color.B;
Color oldColor = (Color)e.OldValue;
uc.PreviousColor = oldColor;
RoutedPropertyChangedEventArgs<Color> args = new RoutedPropertyChangedEventArgs<Color>(oldColor, color);
args.RoutedEvent = ColorChangedEvent;
uc.RaiseEvent(args);
}
public static readonly RoutedEvent ColorChangedEvent = EventManager.RegisterRoutedEvent("ColorChanged", RoutingStrategy.Bubble,
typeof(RoutedPropertyChangedEventHandler<Color>), typeof(ColorPickerUserControl));
public event RoutedPropertyChangedEventHandler<Color> ColorChanged
{
add { AddHandler(ColorChangedEvent, value); }
remove { RemoveHandler(ColorChangedEvent, value); }
}
Color? PreviousColor;
static ColorPickerUserControl()
{
CommandManager.RegisterClassCommandBinding(typeof(ColorPickerUserControl),
new CommandBinding(ApplicationCommands.Undo,Undo_Executed, Undo_CanExecute));
}
private static void Undo_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
ColorPickerUserControl uc = (ColorPickerUserControl)sender;
e.CanExecute = uc.PreviousColor.HasValue;
}
private static void Undo_Executed(object sender, ExecutedRoutedEventArgs e)
{
ColorPickerUserControl uc = (ColorPickerUserControl)sender;
uc.Color = (Color)uc.PreviousColor;
}
}
}
3 主程序
<Window x:Class="CustomControlApp.ColorPickerUserControlTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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"
xmlns:local="clr-namespace:CustomControlApp"
xmlns:lib="clr-namespace:CustomControl;assembly=CustomControl"
mc:Ignorable="d"
Title="ColorPickerUserControlTest" Height="450" Width="800">
<StackPanel>
<lib:ColorPickerUserControl Name="ColorPicker" ColorChanged="ColorPickerUserControl_ColorChanged"/>
<TextBlock x:Name="lblColor"/>
<Button Content="Undo" Command="Undo" CommandTarget="{Binding ElementName=ColorPicker}" />
</StackPanel>
</Window>
using CustomControl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace CustomControlApp
{
/// <summary>
/// ColorPickerUserControlTest.xaml 的交互逻辑
/// </summary>
public partial class ColorPickerUserControlTest : Window
{
public ColorPickerUserControlTest()
{
InitializeComponent();
}
private void ColorPickerUserControl_ColorChanged(object sender, RoutedPropertyChangedEventArgs<Color> e)
{
ColorPickerUserControl uc = (ColorPickerUserControl)sender;
lblColor.Text = $"Current color is {uc.Color}";
}
}
}