トップ回答者
MainWindow直下のコントロールとプロパティーに対してTwoWayバインディングを設定する方法

質問
-
開発環境はVS2010+Windows7です。
MainWindowにはSlider1が配置されており、MainWindowクラスの「SliderValue」プロパティーに連動してスライダーが動くようにしたいです。またスライダーを動かすとMainWindowクラスの「SliderValue」プロパティーも連動して変化させたいです。
「SliderValue」プロパティーはMainWindowクラス外からも操作されるため、Publicとしています。
Sub Button1_Clickをテストボタンとしていますが、「SliderValue」プロパティーに値を代入するとMainWindowのコントロールが消えて「4」という文字だけが表示されてしまいます。
このコードのどこに問題があるのか、教えていただきたいです。
<XAML>
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Slider Height="28" HorizontalAlignment="Left" Margin="78,66,0,0" Name="Slider1" VerticalAlignment="Top" Width="297" />
<Button Content="Button" Height="40" HorizontalAlignment="Left" Margin="74,163,0,0" Name="Button1" VerticalAlignment="Top" Width="176" />
</Grid>
</Window>
<VB.net>
Class MainWindow
Public Property SliderValue As String
Get
Return CType(GetValue(ContentProperty), String)
End Get
Set(value As String)
SetValue(ContentProperty, value)
Debug.Print(value) '←スライダーを動かす度にこの行が実行されて欲しい
End Set
End Property
Public Shared ReadOnly SliderValueProperty As DependencyProperty = DependencyProperty.Register("SliderValue", GetType(String), GetType(MainWindow))
Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
Dim binding1 As New Binding("SliderValue") With {.Source = Me, .Mode = BindingMode.TwoWay}
Me.Slider1.SetBinding(System.Windows.Controls.Slider.ValueProperty, binding1)
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
Me.SliderValue = 4 '←コントロールが消えて「4」という文字が表示されてしまう
End Sub
End Class
回答
-
SliderのValueプロパティはDoubleなのでStringやSingleよりもDoubleのほうがよけいな変換が発生しないので適切ではありますが、原因はそこではありません。
SliderValueプロパティのget,setでContentPropertyに対してGetValue,SetValueしていることが間違いです。
提示されているコードだとWindowのContentプロパティに対してSetValueしてしまっているために、Windowの直下であるContentが書き換わってしまっています。
(WindowはContentControlを継承しているので直下にはContentが表示されます。提示されているXAMLではGirdがContentプロパティに設定されます。)ただしくは新たに追加しているSliderValuePropertyに対してGetValue,SetValueします。
Public Property SliderValue As String Get Return CType(GetValue(SliderValueProperty), String) End Get Set(value As String) SetValue(SliderValueProperty, value) Debug.Print(value) '←スライダーを動かす度にこの行が実行されて欲しい End Set End Property
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク huahi11112 2017年9月18日 5:38
-
質問後に思い付いたのですが、TwoWayバインディングにしなくてもSlider.ValueChangedイベントを利用し、PropertyのGet 及びSetで処理すれば良いとも思いました。
多くの場合、INotifyPropertyChangedインターフェースが使用されます。
(参考)
INotifyPropertyChangedを実装しておこう
http://vb.netde業務アプリ.com/142.htm上記の例とは違いますが、もちろん、MainWindowにINotifyPropertyChangedインターフェースを直接実装してもかまいません。今回のケースではそうするのが簡単だと思います。
★良い回答には回答済みマークを付けよう! MVP - .NET http://d.hatena.ne.jp/trapemiya/
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年9月20日 0:05
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年9月22日 0:25
すべての返信
-
SliderのValueプロパティはDoubleなのでStringやSingleよりもDoubleのほうがよけいな変換が発生しないので適切ではありますが、原因はそこではありません。
SliderValueプロパティのget,setでContentPropertyに対してGetValue,SetValueしていることが間違いです。
提示されているコードだとWindowのContentプロパティに対してSetValueしてしまっているために、Windowの直下であるContentが書き換わってしまっています。
(WindowはContentControlを継承しているので直下にはContentが表示されます。提示されているXAMLではGirdがContentプロパティに設定されます。)ただしくは新たに追加しているSliderValuePropertyに対してGetValue,SetValueします。
Public Property SliderValue As String Get Return CType(GetValue(SliderValueProperty), String) End Get Set(value As String) SetValue(SliderValueProperty, value) Debug.Print(value) '←スライダーを動かす度にこの行が実行されて欲しい End Set End Property
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク huahi11112 2017年9月18日 5:38
-
質問後に思い付いたのですが、TwoWayバインディングにしなくてもSlider.ValueChangedイベントを利用し、PropertyのGet 及びSetで処理すれば良いとも思いました。
多くの場合、INotifyPropertyChangedインターフェースが使用されます。
(参考)
INotifyPropertyChangedを実装しておこう
http://vb.netde業務アプリ.com/142.htm上記の例とは違いますが、もちろん、MainWindowにINotifyPropertyChangedインターフェースを直接実装してもかまいません。今回のケースではそうするのが簡単だと思います。
★良い回答には回答済みマークを付けよう! MVP - .NET http://d.hatena.ne.jp/trapemiya/
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年9月20日 0:05
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年9月22日 0:25