ColorPickerクラス
public partial class ColorPicker : UserControl { private bool IsPropertyChanging; private byte FixedAlpha; private ColorPickerItem CustomItem; public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register( "SelectedColor", // プロパティ名を指定 typeof(Color), // プロパティの型を指定 typeof(ColorPicker), // プロパティを所有する型を指定 new FrameworkPropertyMetadata(Colors.White, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (d, e) => {(d as ColorPicker).OnColorPropertyChanged(e); })); public Color SelectedColor { get { return (Color)GetValue(SelectedColorProperty); } set { SetValue(SelectedColorProperty, value); } } public event SelectionChangedEventHandler SelectionChanged; public ColorPicker() { InitializeComponent(); float r, g, b; var items = new List<ColorPickerItem>(); for (int i = 0; i < 12; ++i) { ColorHelper.HSVtoRGB(0.0f, 0.0f, (float)i / 11.0f, out r, out g, out b); byte ba = 255; byte br = (byte)(r * 255.0f); byte bg = (byte)(g * 255.0f); byte bb = (byte)(b * 255.0f); items.Add(new ColorPickerItem() { CategoryName = "グレースケール", Column = i, Row = 0, ItemColor = Color.FromArgb(ba, br, bg, bb), }); } for (int i = 0; i < 12; ++i) { ColorHelper.HSVtoRGB((float)i / 12.0f, 1.0f, 1.0f, out r, out g, out b); byte ba = 255; byte br = (byte)(r * 255.0f); byte bg = (byte)(g * 255.0f); byte bb = (byte)(b * 255.0f); items.Add(new ColorPickerItem() { CategoryName = "基本の色", Column = i, Row = 1, ItemColor = Color.FromArgb(ba, br, bg, bb), }); } for (int j = 1; j < 5; ++j) { float s = (float)j / 5.0f; for (int i = 0; i < 12; ++i) { ColorHelper.HSVtoRGB((float)i / 12.0f, s, 1.0f, out r, out g, out b); byte ba = 255; byte br = (byte)(r * 255.0f); byte bg = (byte)(g * 255.0f); byte bb = (byte)(b * 255.0f); items.Add(new ColorPickerItem() { CategoryName = "その他の色", Column = i, Row = 2 + j - 1, ItemColor = Color.FromArgb(ba, br, bg, bb), }); } } for (int j = 1; j < 4; ++j) { float v = 1.0f - (float)j / 5.0f; for (int i = 0; i < 12; ++i) { ColorHelper.HSVtoRGB((float)i / 12.0f, 1.0f, v, out r, out g, out b); byte ba = 255; byte br = (byte)(r * 255.0f); byte bg = (byte)(g * 255.0f); byte bb = (byte)(b * 255.0f); items.Add(new ColorPickerItem() { CategoryName = "その他の色", Column = i, Row = 6 + j - 1, ItemColor = Color.FromArgb(ba, br, bg, bb), }); } } CustomItem = new ColorPickerItem() { CategoryName = "カスタム", Column = 0, Row = 9, ItemColor = Colors.Black, }; items.Add(CustomItem); IsPropertyChanging = true; var src = new ListCollectionView(items); src.GroupDescriptions.Add(new PropertyGroupDescription("CategoryName")); Main.ItemsSource = src; FixedAlpha = SelectedColor.A; CustomItem.ItemColor = Color.FromArgb(255, SelectedColor.R, SelectedColor.G, SelectedColor.B); Main.SelectedItem = CustomItem; IsPropertyChanging = false; } private void Hyperlink_Click(object sender, RoutedEventArgs e) { var dialog = new System.Windows.Forms.ColorDialog(); dialog.FullOpen = true; dialog.Color = System.Drawing.Color.FromArgb(SelectedColor.A, SelectedColor.R, SelectedColor.G, SelectedColor.B); if (System.Windows.Forms.DialogResult.OK == dialog.ShowDialog()) { SelectedColor = Color.FromArgb(FixedAlpha, dialog.Color.R, dialog.Color.G, dialog.Color.B); } } private void Main_SelectionChanged(object sender, SelectionChangedEventArgs e) { var item = Main.SelectedItem as ColorPickerItem; if (null == item) return; if (!IsPropertyChanging) { SelectedColor = Color.FromArgb(FixedAlpha, item.ItemColor.R, item.ItemColor.G, item.ItemColor.B); if (null != SelectionChanged) SelectionChanged(this, e); } } public void OnColorPropertyChanged(DependencyPropertyChangedEventArgs e) { var item = Main.SelectedItem as ColorPickerItem; Color col = Colors.Black; col = (Color)e.NewValue; if (null != item) if (item.ItemColor == col) return; IsPropertyChanging = true; FixedAlpha = col.A; CustomItem.ItemColor = col; Main.SelectedItem = CustomItem; IsPropertyChanging = false; } }
SelectedColorプロパティ (8~20行目)
依存関係プロパティとして作成。
FrameworkPropertyMetadataOptionsでBindsTwoWayByDefaultフラグを立ててデフォルトでバインディングがTwoWayモードで動作するようにしている。
SelectionChangedEventHandler (22、143~144行目)
SelectedColorで色を取得する以外に、選択が変更された時のイベントを処理出来るようにEventHandlerを実装。
データソースを作成 (31~115行目)
GridのRow,Columnを指定しながら色毎のColorPickerItemを作成している。
色はHSV形式で数値を決めた後、RGBへ変換している。
HSVからRGBへの変換についてはこちらを参照
Hyperlink_Clickメソッド (124~133行目)
「その他の色...」がクリックされた時の動作を実装。
カラーダイアログを表示して、OKボタンが押されたらSelectedColorプロパティへ色をセット。
FullOpenプロパティをtrueにするとカスタムカラー作成用のコントロールが最初から見える状態で起動できる。
Main_SelectionChangedメソッド (134~146行目)
ComboBoxの選択が変更された時の処理。
SelectedColorプロパティの値のセットしている。
※SelectedColorプロパティを変えるとOnColorPropertyChangedメソッドが呼び出されるが、
そこでComboBoxのSelectedItemが変えられるとMain_SelectionChangedメソッドが呼ばれる
ぐるぐる回ってしまわないようにIsPropertyChangingというフラグで制御している
OnColorPropertyChangedメソッド (148~162行目)
依存関係プロパティによってSelectedColorの値が変更された時に呼び出される。(15行目)
指定された色をカスタム用のColorPickerItemへセットしそれをComboBoxのSelectedItemにする。
※SelectedItemを変えるとMain_SelectionChangedメソッドが呼び出されるが、
そこでSelectedColorプロパティが変えられるとOnColorPropertyChangedメソッドが呼ばれる
ぐるぐる回ってしまわないようにIsPropertyChangingというフラグで制御している
関連記事
- WPFで色選択コントロールを自作する その1
- WPFで色選択コントロールを自作する その2
- WPFで色選択コントロールを自作する その3
- WPFで色選択コントロールを自作する その4
コメントをお書きください
QlqzzNwr (土曜日, 07 8月 2021 04:17)
1