WPF user control
//usercontrol.xaml <UserControl x:Class="WpfControlLibrary1.ColorPicker" 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:WpfControlLibrary1" mc:Ignorable="d" x:Name="uc" d:DesignHeight="450" d:DesignWidth="800"> <UserControl.Resources> <Style TargetType="Rectangle"> <Setter Property="Margin" Value="2"/> <Setter Property="Width" Value="50"/> <Setter Property="Height" Value="30"/> <Setter Property="Stroke" Value="Black"/> <Setter Property="StrokeThickness" Value="3"/> </Style> <Style TargetType="TextBlock"> <Setter Property="Margin" Value="6,0,0,0"/> <Setter Property="Foreground" Value="White"/> <Setter Property="VerticalAlignment" Value="Center"/> <Setter Property="FontSize" Value="14"/> </Style> <Style TargetType="Slider"> <Setter Property="Maximum" Value="255"/> <Setter Property="VerticalAlignment" Value="Center"/> <Setter Property="Margin" Value="10,0,0,0"/> <Setter Property="LargeChange" Value="10"/> </Style> <local:ColorToBrushConverter x:Key="color2brush"/> <local:ColorToDoubleConverter x:Key="color2double"/> </UserControl.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition /> </Grid.RowDefinitions> <Rectangle Grid.Row="4" Margin="4" Style="{x:Null}" StrokeThickness="1" Stroke="Black"> <Rectangle.Fill> <SolidColorBrush Color="{Binding SelectedColor,ElementName=uc}"/> </Rectangle.Fill> </Rectangle> <Grid Margin="4" Grid.Row="0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Rectangle Fill="{Binding SelectedColor,ElementName=uc,Converter={StaticResource color2brush}, ConverterParameter=r}"/> <Slider Grid.Column="1" Value="{Binding SelectedColor,ElementName=uc,Converter={ StaticResource color2double},ConverterParameter=r}"/> <TextBlock Text="{Binding SelectedColor,ElementName=uc,Converter={StaticResource color2double}, ConverterParameter=r,StringFormat=R:{0}}"/> </Grid> <Grid Margin="4" Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Rectangle Fill="{Binding SelectedColor,ElementName=uc,Converter={StaticResource color2brush}, ConverterParameter=g}"/> <Slider Grid.Column="1" Value="{Binding SelectedColor,ElementName=uc, Converter={StaticResource color2double},ConverterParameter=g}"/> <TextBlock Text="{Binding SelectedColor,ElementName=uc, Converter={StaticResource color2double}, ConverterParameter=g,StringFormat=G:{0}}"/> </Grid> <Grid Margin="4" Grid.Row="2"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Rectangle Fill="{Binding SelectedColor,ElementName=uc,Converter={StaticResource color2brush}, ConverterParameter=b}"/> <Slider Grid.Column="1" Value="{Binding SelectedColor,ElementName=uc,Converter={StaticResource color2double}, ConverterParameter=b}"/> <TextBlock Text="{Binding SelectedColor,ElementName=uc, Converter={StaticResource color2double}, ConverterParameter=b,StringFormat=B:{0}}"/> </Grid> <Grid Margin="4" Grid.Row="3"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition /> </Grid.ColumnDefinitions> <Rectangle Fill="{Binding SelectedColor,ElementName=uc, Converter={StaticResource color2brush}, ConverterParameter=a}"/> <Slider Grid.Column="1" Value="{Binding SelectedColor, ElementName=uc,Converter={StaticResource color2double}, ConverterParameter=a}"/> <TextBlock Foreground="Black" Text="{Binding SelectedColor,ElementName=uc,Converter={StaticResource color2double}, ConverterParameter=a,StringFormat=A:{0}}"/> </Grid> </Grid> </UserControl> //usercontrol.xaml.cs 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 WpfControlLibrary1 { /// <summary> /// Interaction logic for ColorPicker.xaml /// </summary> public partial class ColorPicker : UserControl { static ColorPicker() { CommandManager.RegisterClassCommandBinding(typeof(ColorPicker), new CommandBinding( MediaCommands.ChannelUp, ChannelUpExecute, ChannelUpCanExecute)); CommandManager.RegisterClassCommandBinding(typeof(ColorPicker),new CommandBinding( MediaCommands.ChannelDown,ChannelDownExecute, ChannelDownCanExecute)); } private static void ChannelDownCanExecute(object sender, CanExecuteRoutedEventArgs e) { var color = ((ColorPicker)sender).SelectedColor; e.CanExecute=color.R>0 || color.G>0 || color.B>0; } private static void ChannelDownExecute(object sender, ExecutedRoutedEventArgs e) { var cp = (ColorPicker)sender; var color = cp.SelectedColor; if(color.R>0) { color.R--; } if(color.G>0) { color.G--; } if(color.B>0) { color.B--; } cp.SelectedColor = color; } private static void ChannelUpCanExecute(object sender, CanExecuteRoutedEventArgs e) { var color = ((ColorPicker)sender).SelectedColor; e.CanExecute = color.R < 255 || color.G < 255 || color.B < 255; } private static void ChannelUpExecute(object sender, ExecutedRoutedEventArgs e) { var cp = (ColorPicker)sender; var color = cp.SelectedColor; if (color.R < 255) { color.R++; } if (color.G < 255) { color.G++; } if (color.B < 255) { color.B++; } cp.SelectedColor = color; } public ColorPicker() { InitializeComponent(); } public Color SelectedColor { get { return (Color)GetValue(SelectedColorProperty); } set { SetValue(SelectedColorProperty, value); } } // Using a DependencyProperty as the backing store for SelectedColor. This enables animation, styling, binding, etc... public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorPicker), new UIPropertyMetadata(Colors.Black, OnSelectedColorChanged)); public static RoutedEvent SelectedColorChangedEvent = EventManager.RegisterRoutedEvent("SelectedColorChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<Color>), typeof(ColorPicker)); public event RoutedPropertyChangedEventHandler<Color> SelectedColorChanged { add { AddHandler(SelectedColorChangedEvent, value); } remove { RemoveHandler(SelectedColorChangedEvent, value); } } private static void OnSelectedColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { //var cp = d as ColorPicker; //if(cp!=null) //{ // cp.RaiseEvent(new RoutedPropertyChangedEventArgs<Color>( // (Color)e.OldValue, (Color)e.NewValue, // SelectedColorChangedEvent)); //} var cp = d as ColorPicker; var args = new RoutedPropertyChangedEventArgs<Color>((Color)e.OldValue, (Color)e.NewValue, PreviewSelectedColorChangedEvent); cp.RaiseEvent(args); if (!args.Handled) { cp.RaiseEvent(new RoutedPropertyChangedEventArgs<Color>( (Color)e.OldValue, (Color)e.NewValue, SelectedColorChangedEvent)); } } public bool ShowAlphaChannel { get { return (bool)GetValue(ShowAlphaChannelProperty); } set { SetValue(ShowAlphaChannelProperty, value); } } // Using a DependencyProperty as the backing store for ShowAlphaChannel. This enables animation, styling, binding, etc... public static readonly DependencyProperty ShowAlphaChannelProperty = DependencyProperty.Register("ShowAlphaChannel", typeof(bool), typeof(ColorPicker), new UIPropertyMetadata(true)); public static RoutedEvent PreviewSelectedColorChangedEvent = EventManager.RegisterRoutedEvent("PreviewSelectedColorChanged", RoutingStrategy.Tunnel, typeof(RoutedPropertyChangedEventHandler<Color>), typeof(ColorPicker)); public event RoutedPropertyChangedEventHandler<Color> PreviewSelectedColorChanged { add { AddHandler(PreviewSelectedColorChangedEvent, value); } remove { RemoveHandler(PreviewSelectedColorChangedEvent, value); } } } } //BooleanToVisibilityConverter using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Data; namespace WpfControlLibrary1 { public class BooleanToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { bool isTrue= (bool)value; if(isTrue) { return Visibility.Visible; } else { return Visibility.Hidden; } } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } } //ColorToBrushConverter using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using System.Text; using System.Threading.Tasks; using System.Windows.Data; using System.Windows.Media; namespace WpfControlLibrary1 { public class ColorToBrushConverter : IValueConverter { SolidColorBrush _red = new SolidColorBrush(), _green = new SolidColorBrush(), _blue = new SolidColorBrush(), _alpha = new SolidColorBrush(); public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var color = (Color)value; switch((string)parameter) { case "r": _red.Color = Color.FromRgb(color.R, 0, 0); return _red; case "g": _green.Color = Color.FromRgb(0, color.G, 0); return _green; case "b": _blue.Color = Color.FromRgb(0, 0, color.B); return _blue; case "a": _alpha.Color = Color.FromArgb(color.A, 128, 128, 128); return _alpha; } return Binding.DoNothing; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return null; } } } //ColorToDoubleConverter using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; using System.Windows.Media; using System.Globalization; using System.Windows; using System.Windows.Data; using System.Windows.Controls; namespace WpfControlLibrary1 { public class ColorToDoubleConverter : IValueConverter { private Color _lastColor; public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var color = (Color)value; _lastColor = color; switch ((string)parameter) { case "r": return color.R; case "g": return color.G; case "b": return color.B; case "a": return color.A; } return Binding.DoNothing; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { Color color = _lastColor; var intensity = (byte)(double)value; switch((string)parameter) { case "r": color.R = intensity; break; case "g": color.G = intensity; break; case "b": color.B = intensity; break; case "a": color.A=intensity; break; } _lastColor = color; return color; } } }
user:
//xaml <Window x:Class="WpfApp52.MainWindow" 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:WpfApp52" xmlns:ctls="clr-namespace:WpfControlLibrary1;assembly=WpfControlLibrary1" mc:Ignorable="d" WindowState="Maximized" Title="MainWindow" Height="450" Width="800"> <Window.Resources> <ctls:BooleanToVisibilityConverter x:Key="bool2vis"/> </Window.Resources> <Grid Visibility="{Binding ShowAlphaChannel, ElementName=uc,Converter={StaticResource bool2vis}}"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <ctls:ColorPicker SelectedColorChanged="OnColorChanged" /> <TextBlock x:Name="_tbColor" FontSize="20" Text="Customie User Control" Grid.Row="1" Margin="8"/> </Grid> </Window> //xaml.cs 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 WpfApp52 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void OnColorChanged(object sender, RoutedPropertyChangedEventArgs<Color> e) { if(_tbColor!=null) { _tbColor.Text = string.Format("Selected Color:{0}", e.NewValue); } } } }