一,ColorPicker的实现
1,自定义属性
#region ColorPick Of the Book [TemplatePart(Name = "PART_RedSlider", Type = typeof(RangeBase))] [TemplatePart(Name = "PART_BlueSlider", Type = typeof(RangeBase))] [TemplatePart(Name = "PART_GreenSlider", Type = typeof(RangeBase))] [TemplatePart(Name = "PART_PreviewBrush", Type = typeof(SolidColorBrush))]
自定义依赖项属性(propdp模板快速定义)
public static DependencyProperty ColorProperty; public static DependencyProperty RedProperty; public static DependencyProperty GreenProperty; public static DependencyProperty BlueProperty;
static ColorPicker() { //This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class. //This style is defined in themesgeneric.xaml DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorPicker), new FrameworkPropertyMetadata(typeof(ColorPicker))); ColorProperty = DependencyProperty.Register("Color", typeof(Color), typeof(ColorPicker), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnColorChanged))); RedProperty = DependencyProperty.Register("Red", typeof(byte), typeof(ColorPicker), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnColorRGBChanged))); GreenProperty = DependencyProperty.Register("Green", typeof(byte), typeof(ColorPicker), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnColorRGBChanged))); BlueProperty = DependencyProperty.Register("Blue", typeof(byte), typeof(ColorPicker), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnColorRGBChanged))); }
DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorPicker), new FrameworkPropertyMetadata(typeof(ColorPicker))); 用来在themes/generic.xaml中定义默认模板.
2,自定义Command
// Set up command bindings. CommandBinding binding = new CommandBinding(ApplicationCommands.Undo, UndoCommand_Executed, UndoCommand_CanExecute); this.CommandBindings.Add(binding);
private Color? previousColor; private void UndoCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = previousColor.HasValue; } private void UndoCommand_Executed(object sender, ExecutedRoutedEventArgs e) { // Use simple reverse-or-redo Undo (like Notepad). this.Color = (Color)previousColor; }
3,进行触发的颜色变更的跟踪
private static void OnColorChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ColorPicker colorPicker = (ColorPicker)sender; Color oldColor = (Color)e.OldValue; Color newColor = (Color)e.NewValue; colorPicker.Red = newColor.R; colorPicker.Green = newColor.G; colorPicker.Blue = newColor.B; colorPicker.previousColor = oldColor; colorPicker.OnColorChanged(oldColor, newColor); } private static void OnColorRGBChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ColorPicker colorPicker = (ColorPicker)sender; Color color = colorPicker.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; colorPicker.Color = color; }
5自定义RouteEvent事件
public static readonly RoutedEvent ColorChangedEvent = EventManager.RegisterRoutedEvent("ColorChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<Color>), typeof(ColorPicker)); public event RoutedPropertyChangedEventHandler<Color> ColorChanged { add { AddHandler(ColorChangedEvent, value); } remove { RemoveHandler(ColorChangedEvent, value); } } private void OnColorChanged(Color oldValue, Color newValue) { RoutedPropertyChangedEventArgs<Color> args = new RoutedPropertyChangedEventArgs<Color>(oldValue, newValue); args.RoutedEvent = ColorPicker.ColorChangedEvent; RaiseEvent(args); }
6,重新架构OnApply()来进行数据绑定或者别的工作
public override void OnApplyTemplate() { base.OnApplyTemplate(); RangeBase slider = GetTemplateChild("PART_RedSlider") as RangeBase; if (slider != null) { Binding binding = new Binding("Red"); binding.Source = this; binding.Mode = BindingMode.TwoWay; slider.SetBinding(RangeBase.ValueProperty, binding); } slider = GetTemplateChild("PART_GreenSlider") as RangeBase; if (slider != null) { Binding binding = new Binding("Green"); binding.Source = this; binding.Mode = BindingMode.TwoWay; slider.SetBinding(RangeBase.ValueProperty, binding); } slider = GetTemplateChild("PART_BlueSlider") as RangeBase; if (slider != null) { Binding binding = new Binding("Blue"); binding.Source = this; binding.Mode = BindingMode.TwoWay; slider.SetBinding(RangeBase.ValueProperty, binding); } SolidColorBrush brush = GetTemplateChild("PART_PreviewBrush") as SolidColorBrush; if (brush != null) { Binding binding = new Binding("Color"); binding.Source = brush; binding.Mode = BindingMode.OneWayToSource; this.SetBinding(ColorPicker.ColorProperty, binding); } } }
7,默认的模板查看
<Style TargetType="{x:Type local:ColorPicker}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:ColorPicker}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <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="PART_RedSlider" Minimum="0" Maximum="255" Margin="{TemplateBinding Padding}"></Slider> <Slider Grid.Row="1" Name="PART_GreenSlider" Minimum="0" Maximum="255" Margin="{TemplateBinding Padding}"></Slider> <Slider Grid.Row="2" Name="PART_BlueSlider" Minimum="0" Maximum="255" Margin="{TemplateBinding Padding}"></Slider> <Rectangle Grid.Column="1" Grid.RowSpan="3" Margin="{TemplateBinding Padding}" Width="50" Stroke="Black" StrokeThickness="1"> <Rectangle.Fill> <SolidColorBrush Color="{Binding Path=Color, RelativeSource={RelativeSource TemplatedParent}}"></SolidColorBrush> </Rectangle.Fill> </Rectangle> </Grid> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>