WPFでコントロールを別クラスとバインディングする方法
C#/WPFにて、コントロールと別のクラスを上手くバインディングすることが出来ず困っています。
ViewModelから、コントロール(Button)に対応した別のクラスを経由して、画面に値を設定したいと思っています。
しかし画面に反映することができないため質問します。
※補足です
ここでは、MainWindow.xaml, MainWindow.xaml.cs の2ファイルは変更しないことを前提とさせてください。
XAMLにて DataContext="{Binding Btn1}
と書いているのは間違えているわけではありません。
XAMLでは、ButtonにはDataContextのみを指定し、Contentは指定しないこととします。
ちなみに、本来やりたいことはもう少し複雑で、
最終的にはこれを発展させ、Buttonを継承したMyButtonを画面に設置、MyButtonとButtonDataをViewModelを経由してBindingする、という形を取ることになります。
構成
プロジェクトの構成(主なもの)は以下の通りです。
- MainWindow.xaml
- MainWindow.xaml.cs
- ViewModel.cs
- ButtonData.cs
MainWindow.xaml.cs
MainWindow は DataContextにViewModelを指定します。
[MainWindows.xaml.cs]
cs
1 public partial class MainWindow : Window 2 { 3 public MainWindow() 4 { 5 InitializeComponent(); 6 this.DataContext = new ViewModel(); 7 } 8 }
MainWindow.xaml
画面にはボタンを一つだけ設置します。
Btn1のDataContextには、ViewModelの"Btn1"というプロパティをバインドします。
[MainWindow.xaml]
cs
1<Window x:Class="WpfApplication2.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfApplication2" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="350" Width="525"> 9 <Grid> 10 <Button x:Name="Btn1" DataContext="{Binding Btn1,Mode=TwoWay}" /> 11 </Grid> 12</Window>
ButtonData.cs
ButtonDataは、コントロールのButtonクラスに対応するクラスです。
ViewModelからはButtonクラスではなく、このButtonDataクラスのContentプロパティに値をセットすることで、画面に文字を反映しようとします。
cs
1 public class ButtonData : INotifyPropertyChanged 2 { 3 public ButtonData() { } 4 5 private string _Content; 6 public string Content 7 { 8 get 9 { 10 return this._Content; 11 } 12 set 13 { 14 if (this._Content == value) 15 return; 16 this._Content = value; 17 OnPropertyChanged("Content"); 18 } 19 } 20 21 public event PropertyChangedEventHandler PropertyChanged; 22 protected void OnPropertyChanged(string name) 23 { 24 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 25 } 26 }
ViewModel.cs
最後にViewModelクラスです。
ViewModelには、MainWindow.xamlに設置したボタン"Btn1"に対応するプロパティ"Btn1"を用意します。
ViewModel上で、Btn1.Contentに値をセットすると、これが画面に反映されることを想定しています。
cs
1 public class ViewModel : INotifyPropertyChanged 2 { 3 public ViewModel() 4 { 5 var button = new ButtonData(); 6 button.Content = "hello"; 7 Btn1 = button; 8 } 9 10 private ButtonData _Btn1; 11 public ButtonData Btn1 12 { 13 get 14 { 15 return _Btn1; 16 } 17 set 18 { 19 _Btn1 = value; 20 OnPropertyChanged("Btn1"); 21 } 22 } 23 24 public event PropertyChangedEventHandler PropertyChanged; 25 protected void OnPropertyChanged(string name) 26 { 27 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 28 } 29 }
疑問
上記のようにコードを作成しました。
想定では、画面に表示されるボタンに"hello"と表示されるはずでしたが、何も表示されません。
なぜボタンには何も表示されないのでしょうか。
(ここではButtonDataやViewModelクラスを必ず使用する、という前提の質問です。)
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/01/26 14:07
2017/01/26 14:24
2017/01/26 14:26
2017/01/26 14:26
2017/01/26 14:28
2017/01/26 14:35
2017/01/26 14:45
2017/01/26 14:47
2017/01/26 14:51
2017/01/26 14:54
2017/01/26 15:07