午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

WPF、CanvasLeftTopとSliderValueをBinding

 
Canvasに表示したBorderの
Canvas.LeftとCanvas.Topを
SliderのValueにBinding
VBのコードでBinding
イメージ 1
今回のアプリのダウンロード先
 
 
デザイン画面、XAML

f:id:gogowaten:20191031141350p:plain

 
MainWindowのVBコード
Class MainWindow
   '右へ10
    Private Sub AddLeft10()
        Canvas.SetLeft(MyBorder, Canvas.GetLeft(MyBorder) + 10)
    End Sub
   '左へ10
    Private Sub SubLeft10()
        Canvas.SetLeft(MyBorder, Canvas.GetLeft(MyBorder) - 10)
    End Sub
   'バインディング作成用
    Private Function GetMyBinding(sObj As DependencyObject, sDp As DependencyProperty, strF As String) As Binding
        Dim b As New Binding With {
           .Source = sObj,
           .Path = New PropertyPath(sDp),
           .Mode = BindingMode.TwoWay,
           .StringFormat = strF}
        Return b
    End Function
    Private Sub MainWindow_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized
       'ボタンのクリックイベントに関連付け
        AddHandler btAdd10.Click, AddressOf AddLeft10
        AddHandler btSub10.Click, AddressOf SubLeft10

       'バインディング
        Dim bindL As Binding = GetMyBinding(MyBorder, Canvas.LeftProperty, "CanvasLeft = {0:0.0}")
        sldCanvasLeft.SetBinding(Slider.ValueProperty, bindL)
        tbCanvasLeft.SetBinding(TextBlock.TextProperty, bindL)
        Dim bindT As Binding = GetMyBinding(MyBorder, Canvas.TopProperty, "CanvasTop = {0:0.0}")
        sldCanvasTop.SetBinding(Slider.ValueProperty, bindT)
        tbCanvasTop.SetBinding(TextBlock.TextProperty, bindT)
    End Sub
End Class

今までのに比べたらDependencyPropertyも使っていないしMultiBindingでもないので単純なBinding
これを少し変更してDependencyPropertyを書き加えたのが
(背景色紫が変更したところで背景色水色が書き加えたところ)

Class MainWindow
   '右へ10
    Private Sub AddLeft10()
        MyLeft += 10
    End Sub
   '左へ10
    Private Sub SubLeft10()
        MyLeft -= 10
    End Sub
’LeftとTopの値用のDependencyProperty

    Public Shared ReadOnly MyLeftProperty As DependencyProperty = DependencyProperty.Register(
        NameOf(MyLeft), GetType(Double), GetType(Border), New PropertyMetadata(0.0))
    Public Property MyLeft As Double
        Get
            Return GetValue(MyLeftProperty)
        End Get
        Set(value As Double)
            SetValue(MyLeftProperty, value)
        End Set
    End Property
    Public Shared ReadOnly MyTopProperty As DependencyProperty = DependencyProperty.Register(
        NameOf(MyTop), GetType(Double), GetType(Border), New PropertyMetadata(0.0))
    Public Property MyTop As Double
        Get
            Return GetValue(MyTopProperty)
        End Get
        Set(value As Double)
            SetValue(MyTopProperty, value)
        End Set
    End Property

   'バインディング作成用
    Private Function GetMyBinding(sObj As DependencyObject, sDp As DependencyProperty, strF As String) As Binding
        Dim b As New Binding With {
           .Source = sObj,
           .Path = New PropertyPath(sDp),
           .Mode = BindingMode.TwoWay,
           .StringFormat = strF}
        Return b
    End Function
    Private Sub MainWindow_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized
       'ボタンのクリックイベントに関連付け
        AddHandler btAdd10.Click, AddressOf AddLeft10
        AddHandler btSub10.Click, AddressOf SubLeft10

       'バインディング
        Dim bindL As Binding = GetMyBinding(Me, MyLeftProperty, "MyLeft = {0:0.0}")
        MyBorder.SetBinding(LeftProperty, bindL)
        sldCanvasLeft.SetBinding(Slider.ValueProperty, bindL)
        tbCanvasLeft.SetBinding(TextBlock.TextProperty, bindL)

        Dim bindT As Binding = GetMyBinding(Me, MyTopProperty, "MyTop = {0:0.0}")
        MyBorder.SetBinding(TopProperty, bindT)
        sldCanvasTop.SetBinding(Slider.ValueProperty, bindT)
        tbCanvasTop.SetBinding(TextBlock.TextProperty, bindT)
    End Sub
End Class
 

Class MainWindow

'右へ10
Private Sub AddLeft10()
Canvas.SetLeft(MyBorder, Canvas.GetLeft(MyBorder) + 10)
End Sub
'左へ10
Private Sub SubLeft10()
Canvas.SetLeft(MyBorder, Canvas.GetLeft(MyBorder) - 10)
End Sub

Private Function GetMyBinding(sObj As DependencyObject, sDp As DependencyProperty, strF As String) As Binding
Dim b As New Binding With {
  .Source = sObj,
  .Path = New PropertyPath(sDp),
  .Mode = BindingMode.TwoWay,
  .StringFormat = strF}
Return b
End Function

Private Sub MainWindow_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized
'ボタンのクリックイベントに関連付け
AddHandler btAdd10.Click, AddressOf AddLeft10
AddHandler btSub10.Click, AddressOf SubLeft10
 
Dim bindL As Binding = GetMyBinding(MyBorder, Canvas.LeftProperty, "CanvasLeft = {0:0.0}")
sldCanvasLeft.SetBinding(Slider.ValueProperty, bindL)
tbCanvasLeft.SetBinding(TextBlock.TextProperty, bindL)
Dim bindT As Binding = GetMyBinding(MyBorder, Canvas.TopProperty, "CanvasTop = {0:0.0}")
sldCanvasTop.SetBinding(Slider.ValueProperty, bindT)
tbCanvasTop.SetBinding(TextBlock.TextProperty, bindT)
End Sub

End Class

 
今までのに比べたらDependencyPropertyも使っていないしMultiBindingでもないので単純なBinding
これを少し変更してDependencyPropertyを書き加えたのが
(背景色紫が変更したところ背景色水色が書き加えたところ)
 

Class MainWindow

'右へ10
Private Sub AddLeft10()
MyLeft += 10
End Sub
'左へ10
Private Sub SubLeft10()
MyLeft -= 10
End Sub

’LeftとTopの値用のDependencyProperty
 
Public Shared ReadOnly MyLeftProperty As DependencyProperty = DependencyProperty.Register(
NameOf(MyLeft), GetType(Double), GetType(Border), New PropertyMetadata(0.0))
Public Property MyLeft As Double
Get
Return GetValue(MyLeftProperty)
End Get
Set(value As Double)
SetValue(MyLeftProperty, value)
End Set
End Property

Public Shared ReadOnly MyTopProperty As DependencyProperty = DependencyProperty.Register(
NameOf(MyTop), GetType(Double), GetType(Border), New PropertyMetadata(0.0))
Public Property MyTop As Double
Get
Return GetValue(MyTopProperty)
End Get
Set(value As Double)
SetValue(MyTopProperty, value)
End Set
End Property

 
Private Function GetMyBinding(sObj As DependencyObject, sDp As DependencyProperty, strF As String) As Binding
Dim b As New Binding With {
  .Source = sObj,
  .Path = New PropertyPath(sDp),
  .Mode = BindingMode.TwoWay,
  .StringFormat = strF}
Return b
End Function

Private Sub MainWindow_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized
'ボタンのクリックイベントに関連付け
AddHandler btAdd10.Click, AddressOf AddLeft10
AddHandler btSub10.Click, AddressOf SubLeft10
 
Dim bindL As Binding = GetMyBinding(Me, MyLeftProperty, "MyLeft = {0:0.0}")
MyBorder.SetBinding(LeftProperty, bindL)
sldCanvasLeft.SetBinding(Slider.ValueProperty, bindL)
tbCanvasLeft.SetBinding(TextBlock.TextProperty, bindL)
 
Dim bindT As Binding = GetMyBinding(Me, MyTopProperty, "MyTop = {0:0.0}")
MyBorder.SetBinding(TopProperty, bindT)
sldCanvasTop.SetBinding(Slider.ValueProperty, bindT)
tbCanvasTop.SetBinding(TextBlock.TextProperty, bindT)
End Sub

End Class

 
動作の結果は全く同じ
MyLeftとMyTopっていう2つのDependencyPropertyを用意して
LeftPropertyとTopPropertyにBindingしたので
Canvas.SetLeftとCanvas.SetTopを使わなくても良くなった
 
 
 
最終的な目的は
Thumbをマウスドラッグ移動する
移動は指定したGridに合わせて移動(snap to grid)
回転や拡大など変形後の大きさを考えてGridに合わせて移動
 
一年前にも挑戦してだいたいできたんだけど今一歩だった
WPFVB.NET、回転したコントロールをマウスドラッグでグリッドスナップ、SortedListはスゴイヤツ ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/14136957.html
 
このあと少し改善したけどイマイチな結果だった
このときの記事を見返してみると結構いろいろなことしていた割には
Bindingを使っていないんだなあっていうのと
全く記憶に無いこともいくつかあって驚くw
SortedListとかぜんぜん憶えていない、さすがの記憶力
 
夏がもう少し涼しければいいんだけどねえ
 
今回のコード
改変後
 
 
 
前回の記事、2017/06/23
WPF、Borderの背景色(Background.Brush)とスライダーの値を双方向バインディング? ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/14987741.html
 
次の記事 2017/06/29は5日後
WPF、変形した要素を指定位置に移動、NotifyProperty - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/14998511.html