目的
MultiBindingとIMultiValueConverterを使って
Borderの背景色(Background.Brush)とスライダーの値を双方向バインディング
背景色(Background.Brush)←→スライダー
↑
ボタンで変更
期待どおりの動きなんだけど…
デザイン画面
ヤフーブログのかんたんモードでXAMLを書くと投稿エラーになるから画像で
VBのコード
Imports System.Globalization
'RGB各色の値をSolidColorBrushに変換する
Public Class MyConverterRGB2Brush
Implements IMultiValueConverter
'RGB各値を使ってブラシを作って返す
Public Function Convert(values() As Object,
targetType As Type,
parameter As Object,
culture As CultureInfo) As Object Implements IMultiValueConverter.Convert
'Throw New NotImplementedException()
Dim b As New SolidColorBrush(Color.FromRgb(values(0), values(1), values(2)))
Return b
End Function
'parameterに値を設定したい要素を渡す、今回は各スライダーのあるMainWindow
'ブラシの色をRGB各値に変換
Public Function ConvertBack(value As Object,
targetTypes() As Type,
parameter As Object,
culture As CultureInfo) As Object() Implements IMultiValueConverter.ConvertBack
'Throw New NotImplementedException()
Dim c As MainWindow = parameter
Dim b As SolidColorBrush = value
'スライダーに値設定
c.sldR.Value = b.Color.R
c.sldG.Value = b.Color.G
c.sldB.Value = b.Color.B
Return New Object() {} '空を返している
End Function
End Class
Class MainWindow
Private Sub SetSolidColorBrush()
MyBorder.Background = New SolidColorBrush(Color.FromRgb(255, 180, 50))
End Sub
Private Sub SetBrushes()
MyBorder.Background = Brushes.AliceBlue
End Sub
Private Sub MainWindow_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized
AddHandler btSetColor1.Click, AddressOf SetSolidColorBrush
AddHandler btSetColor2.Click, AddressOf SetBrushes
'RGB各色のスライダーをソースにしてバインディングを作成
Dim bindR As New Binding With {.Source = sldR, .Path = New PropertyPath(Slider.ValueProperty), .Mode = BindingMode.TwoWay}
Dim bindG As New Binding With {.Source = sldG, .Path = New PropertyPath(Slider.ValueProperty), .Mode = BindingMode.TwoWay}
Dim bindB As New Binding With {.Source = sldB, .Path = New PropertyPath(Slider.ValueProperty), .Mode = BindingMode.TwoWay}
'マルチバインディング作成
Dim mb As New MultiBinding
With mb
.Converter = New MyConverterRGB2Brush
.Mode = BindingMode.TwoWay
.ConverterParameter = Me 'これ大事
'3つのバインディングを詰め込む
With .Bindings
.Add(bindR) : .Add(bindG) : .Add(bindB)
End With
End With
'BorderのBackground(Brush)にマルチバインディング
MyBorder.SetBinding(Border.BackgroundProperty, mb)
MyBorder.Background = Brushes.Blue
End Sub
End Class
背景色の指定はBackgroundPropertyにBrushを指定する
Brushの色はRGB各色で指定するので3つの値が必要
背景色1つに対して3つの値とバインディングするのでMultiBinding(マルチバインディング)する必要がある
マルチバインディングにはMultiValueConverterが必要
RGBとBrushを相互変換?するMultiValueConverter
問題なくできたのはRGB3つの値をBrushに変換するConvert(7行目~14行目)
Values()の中には入れた順番に3つの値が入っているから、それを取り出してSolidColorBrushを作成してそれを返している、これはOK
できなかったのがBrushの色のRGBを取り出して返す方のConvertBack(18行目)、できなかったので空っぽのObjectを返している(何か返さないとエラーっぽくなる)
最初に書いたのが
Public Function ConvertBack(value As Object, targetTypes() As Type, parameter As Object, culture As CultureInfo) As Object() Implements IMultiValueConverter.ConvertBack
Dim b As SolidColorBrush = value
Dim obj() As Object = New Object() {b.Color.R, b.Color.G, b.Color.B}
Return obj
End Function
3つの値は返せているはずなんだけどスライダーの値は変化してくれなかったので、今回はConvertBackの引数のparameterを使う方法になった
parameterにMainWindowを入れて渡す
これを受け取ったConverterの方では
なのでこれはバインディングじゃない気がするんだよねえ
変な方法になったけど一応動いた感じ
今回のコード全部
関連記事
2017/06/20
WPF、ScaleTransformと作成した依存プロパティをBinding ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/14981395.html