Quantcast
Channel: 午後わてんのブログ
Viewing all articles
Browse latest Browse all 420

Borderの背景色(Background.Brush)とスライダーの値を双方向バインディング?

$
0
0

目的
MultiBindingとIMultiValueConverterを使って
Borderの背景色(Background.Brush)とスライダーの値を双方向バインディング
イメージ 1
ボタンはBorderの背景色を変更しているだけでスライダーの値には触っていない

背景色(Background.Brush)←→スライダー
ボタンで変更

期待どおりの動きなんだけど…



デザイン画面
ヤフーブログのかんたんモードでXAMLを書くと投稿エラーになるから画像で
イメージ 2


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
イメージ 3
実際には相互変換していない、できなかった

問題なくできたのは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を入れて渡す

イメージ 4

MultiBindingのConverterParameterにMe(MainWindow)を入れる(57行目)
これを受け取ったConverterの方では

イメージ 5

RGBの各スライダーにアクセスできるから直接値を設定している
なのでこれはバインディングじゃない気がするんだよねえ
変な方法になったけど一応動いた感じ



今回のコード全部


関連記事
2017/06/20
WPF、ScaleTransformと作成した依存プロパティをBinding ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/14981395.html











Viewing all articles
Browse latest Browse all 420

Trending Articles