WPFとVB.NETでカラーピッカーその4、パレットを作って色を登録できるようにした
前回は3日前
の続き
WPFとVB.NETでカラーピッカーその3、元の色の明るさ(輝度)に合わせた別の色(色相)を選びたい ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14039932.html
http://blogs.yahoo.co.jp/gogowaten/14039932.html
カラーピッカーに色を登録するパレットをつけた
色が決まったら登録したいマスを右クリックして色を追加(登録)する
削除するときも削除したいマスを右クリックから色の削除
登録した色はファイルとして記録されるので次回起動時に引き継がれる
パレットをクリックで新しい色のところの色が変わる
パレット部分はWrapPanelにマスとなるBorderコントロールを流し込んでいる
必要な処理
- パレットの色データをファイルとして保存
- パレットの色データのファイルを読み込む
- 色の追加
- 色の削除
- 右クリックメニューの作成
- マスをクリックした時に新しい色をマスの色と同じにする
- マスを作成する
1番のパレットの色データをファイルとして保存
ファイルに保存するにはシリアライズするんだけど
調べた感じではWPFのColorもできるっぽいけど難しくてわからなかったので
別の方法
色のデータとして必要なのはARGB各値、4つのbyte型だけなので
新たにIntARGBっていうStructureを作った
Integer型にしたけど素直にbyte型のが良かったかも
どっちでもシリアライズできるはず
これを追加した場所は
MainWindowクラスの外側
<serializabla>を頭につけてシリアライズできます宣言しておく
このIntARGBはマスの個数分作るのでこれをまとめてリストにして入れておくために
ObservableCollectionを継承したPaletteARGBっていうクラスを作成
これにもシリアライズできます宣言の<Serializable>を付ける
あとはこれをMainWindowクラスの方で適当な名前の変数に入れて使う
PaletteARGBを入れた変数の名前はPaletteDataARGBにした
これをシリアライズしてファイルに保存することになる
グローバル変数っていうのかな、クラスのどこからでも参照できる変数
これを増やすのは良くないみたい、でもどんどん増えるYO
FocusPalette
現在選択中のマス(Border)の目印用
PaletteColors
すべてのマスを入れておくリスト
マスの色は背景色(Background)でこれにはSolidColorBrushを指定するから
IntARGBとSolidColorBrushをそれぞれに変換する関数が
’IntARGBをSolidColorBrushに変換
Public Function ARGBtoSolidBrush(argb As IntARGB) As SolidColorBrush
Return New SolidColorBrush(Color.FromArgb(argb.A, argb.R, argb.G, argb.B))
End Function
’SolidColorBrushをIntARGBに変換する関数
Public Function SolidBrushtoARGB(b As SolidColorBrush) As IntARGB
Dim col As Color = b.Color
Return New IntARGB(col.A, col.R, col.G, col.B)
End Function
これで色データをシリアライズする準備ができた
1.パレットの色データをファイルとして保存
'パレットデータをシリアライズしてファイルに保存
Private Sub SavePaletteData()
Dim appPath As String = My.Application.Info.DirectoryPath
Dim fileName As String = "PaletteColorData.bin"
Dim filePath As String = appPath & "\" & fileName
Try
Using fs As New FileStream(filePath, FileMode.Create)
Dim bf As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
bf.Serialize(fs, PaletteDataARGB)
End Using
Catch ex As Exception
Dim str As String = "ファイルの保存に失敗しました" & vbNewLine
MsgBox(str & ex.Message)
End Try
End Sub
ファイルの保存場所はアプリの実行ファイルと同じフォルダ
ファイル名はPaletteColorData.binにした
PaletteDataARGBが色情報のリスト
My.Application.Info.DirectoryPath
これで実行ファイルの場所取得
2.パレットの色データのファイルを読み込む
'パレットデータをデシリアライズして読み込む
Private Sub LoadPaletteData()
Dim appPath As String = My.Application.Info.DirectoryPath
Dim fileName As String = "PaletteColorData.bin"
Dim filePath As String = appPath & "\" & fileName
'ファイルが存在しなければなにもしないで終了
If File.Exists(filePath) = False Then Exit Sub
Try
Using fs As New FileStream(filePath, FileMode.Open)
Dim bf As New Runtime.Serialization.Formatters.Binary.BinaryFormatter
PaletteDataARGB = bf.Deserialize(fs)
End Using
Catch ex As Exception
Dim str As String = "ファイルの読み込みに失敗しました" & vbNewLine
MsgBox(str & ex.Message)
End Try
End Sub
PaletteDataARGBにファイルからデシリアライズしたものを取得している
取得した色情報をマスに反映する処理が
'読み込んだデータをPaletteに反映させる
For i As Integer = 0 To PaletteDataARGB.Count - 1
PaletteColors(i).Background = ARGBtoSolidBrush(PaletteDataARGB(i))
Next
PaletteDataARGBが色情報のリスト
ARGBtoSolidBrushはIntARGBをSolidColorBrushに変換する関数
3.色の追加
Private Sub PaletteAddColor()
FocusPalette.Background = rectMihon.Fill
Dim i As Integer = PaletteColors.IndexOf(FocusPalette)
PaletteDataARGB(i) = SolidBrushtoARGB(FocusPalette.Background)
'パレットデータをセーブ
Call SavePaletteData()
End Sub
4.色を削除
Private Sub PaletteColorDelete()
FocusPalette.Background = New SolidColorBrush(Colors.Transparent)
Dim i As Integer = PaletteColors.IndexOf(FocusPalette)
PaletteDataARGB(i) = New IntARGB(Colors.Transparent)
'パレットデータをセーブ
Call SavePaletteData()
End Sub
新しい色で表示している色を選択中のマスにコピー
マスの色を色情報を書き込み
色情報をファイルに保存
っていう流れ
rectMihonが新しい色を表示しているRectangle
FocusPaletteが選択中のマス、これを使ってマスのリストの何番目のマスなのかを取得しているのが
Dim i As Integer = PaletteColors.IndexOf(FocusPalette)
色情報のリストとマスのリストの順番は一致しているので
同じ番号のところに色情報を書き込みしているのが
PaletteDataARGB(i) = SolidBrushtoARGB(FocusPalette.Background)
色の削除は透明色を指定している
5.右クリックメニューの作成
Private Function AddContextMeruPalette() As ContextMenu
'右クリックメニュー作成
Dim cm As New ContextMenu
Dim mi As New MenuItem
mi.Header = "色を追加"
cm.Items.Add(mi)
AddHandler mi.Click, AddressOf PaletteAddColor
Dim mi2 As New MenuItem
mi2.Header = "色を削除"
cm.Items.Add(mi2)
AddHandler mi2.Click, AddressOf PaletteColorDelete
Return cm
End Function
6.マスをクリックした時に新しい色をマスの色と同じにする
'Paletteクリックした時、hsvとαの各スライダーを変化させる
Private Sub Palette_Click(sender As Object, e As RoutedEventArgs)
Dim b As SolidColorBrush = FocusPalette.Background
'透明色(アルファ値が0)なら何もしないで終了
If b.Color.A = 0 Then Return
sldA.Value = b.Color.A
End Sub
7.マスを作成する
'選択中のPaletteを変更
Private Sub FocusedPalette(sender As Object, e As RoutedEventArgs)
FocusPalette = sender
End Sub
'Palette用のBorder作成して追加
Private Sub AddPalette()
'右クリックメニュー作成
Dim cm As ContextMenu = AddContextMeruPalette()
'Palette作成
For i As Integer = 0 To 100
Dim r As New Border
With r
.Background = New SolidColorBrush(Colors.Transparent) '最初は透明色を指定
.Width = 20
.Height = 20
.BorderThickness = New Thickness(1)
.BorderBrush = New SolidColorBrush(Colors.LightGray)
.Margin = New Thickness(2, 2, 0, 0)
.ContextMenu = cm '右クリックメニュー指定
End With
'WrapPanelに追加
wpPalette.Children.Add(r)
'イベントとメソッドの関連付け
AddHandler r.PreviewMouseDown, AddressOf FocusedPalette
AddHandler r.MouseLeftButtonDown, AddressOf Palette_Click
'Borderのリストに追加
PaletteColors.Add(r)
'シリアライズ用のリストにARGBを追加
PaletteDataARGB.Add(SolidBrushtoARGB(r.Background))
Next
''デシリアライズでパレットデータを読み込んで反映
Call UpdatePalette()
End Sub
マスを101個作成してそれぞれに色々設定
PreviewMouseDownイベントに選択中のマスを切り替える処理の
FocusedPaletteを指定しているのが
AddHandler r.PreviewMouseDown, AddressOf FocusedPalette
このAddPaletteメソッドはアプリが起動し終わった時に実行することにしたので
Me.Loadedのところで呼び出し
縦に長過ぎるwレイアウトが⊂ミ⊃^ω^ )⊃ アウアウ!!
色のスライダーと登録するパレットが離れているのはどうにかするとして
プログラムもイマイチなところがあるけど
機能的にはかなり満足できるものができた!
コード
Wpf_test93_カラーピッカー4 - Visual Studio Team Services
https://gogowaten.visualstudio.com/DefaultCollection/WPF/_git/WPF_test6?path=%2FWpf_test93_%E3%82%AB%E3%83%A9%E3%83%BC%E3%83%94%E3%83%83%E3%82%AB%E3%83%BC4&version=GBmaster&_a=contents
https://gogowaten.visualstudio.com/DefaultCollection/WPF/_git/WPF_test6?path=%2FWpf_test93_%E3%82%AB%E3%83%A9%E3%83%BC%E3%83%94%E3%83%83%E3%82%AB%E3%83%BC4&version=GBmaster&_a=contents
WPFとVB.NETでカラーピッカーその5、もっと色を登録できるようにした ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14058386.html
http://blogs.yahoo.co.jp/gogowaten/14058386.html