デフォルトコントロールみたいな UserControl を作りたい
◆ デフォで用意されてる UserControl みたいな使い方できるようにしたい
◆ DependencyProperty 作ったらその値を Binding どうするの?
◆ DataContext を this にするの?
◆ ソースを適当に見た感じだと DataContext は使ってなくて Binding もほとんどない
◆ MVVM じゃなくて 昔ながらの方法ぽい
◆ DependencyProperty 作ったらその値を Binding どうするの?
◆ DataContext を this にするの?
◆ ソースを適当に見た感じだと DataContext は使ってなくて Binding もほとんどない
◆ MVVM じゃなくて 昔ながらの方法ぽい
UserControl をつくるときに DataContext を使った Binding をしようとすると よく困ることがあります
TestUserControl という UserControl を作って num というプロパティを持たせます
このプロパティは TextBox の Text みたいに Binding で扱えるようにしたいとします
Binding できるようにするには DepedencyProperty を UserControl に作ることになります
という感じ
DataContext に Binding するとしたら この num と TextBox などのコントロールのプロパティを Binding することになります
通常は DataContext 用の (ViewModel となる) クラスを作って そこをソースとして Binding するのですが この場合 Binding のソースにしたい num は TestUserControl のプロパティです
DataContext を使うなら
になります
あまり this を DataContext にしたくないので 別の方法にしたいです
他の方法だと SetBinding を使ってコード側でひとつひとつ Binding を書いていくことができます
これだと Source に this を設定しますが その Binding のプロパティのみに使われるので 問題が起きることもなさそうです
でもこれって結構面倒ですし XAML の良さがなくなるように思います
デフォルトの UserControl って本当にこうやって作られてるの??
目指すは TextBox などの組み込みの UserControl と同じ感じに使えるものなのでとりあえず framework のソースを見てみるのが一番です
https://referencesource.microsoft.com/
いくつかコントロールを見ましたが どれもコードが長いです
シンプルで読みやすいのを探してるのですけどねー
WPF は WinForms と違ってデフォルトコントロールは少なめです
内部に TextBox を持っていて動きもシンプルそうな NumericUpDown でもあればイメージが掴めそうなのにないんです
とりあえず ComboBox や DatePicker や PasswordBox あたりを流し見した感じ DataContext は使って無くて一部スタイルぽいところを SetBinding してるくらいです
内部で TextBox のインスタンスを持っていて 変更イベント時に何かして と WinForms とあんまり変わらない感じの作りのようです
XAML で書くとめったに x:Name をつけないので UserControl や Window からコントロールにアクセスすることはほとんどないですが デフォルトコントロールの作りでは直接コントロールアクセスしてる感じです
WPF は MVVM だー なんて言われてますが内部実装はそうでもないのですね
「デフォルトコントロールみたいに使えるユーザコントロール作りたいけど MVVM でどうすればいいかわからなーい」 という疑問の答えは 作り方が違う です
UserControl 作るときは DataContext を持たずに デフォルトコントロールに近い感じで作っておいたほうが 使い勝手も近くなりますし VM ぽいことをしないのもありかなって思います
普段書く 何か目的のものを作るコードは 見やすさや変更が楽にできることを重視で 速度はそれほどこだわらないけど ライブラリを作る場合はムダを削って速度が出来る限り遅くないようにしたい というのに近いかも
TestUserControl という UserControl を作って num というプロパティを持たせます
このプロパティは TextBox の Text みたいに Binding で扱えるようにしたいとします
Binding できるようにするには DepedencyProperty を UserControl に作ることになります
public partial class TestUserControl : UserControl
public TestUserControl()
{
InitializeComponent();
}
public int num
{
get { return (int)GetValue(numProperty); }
set { SetValue(numProperty, value); }
}
// Using a DependencyProperty as the backing store for num. This enables animation, styling, binding, etc...
public static readonly DependencyProperty numProperty =
DependencyProperty.Register("num", typeof(int), typeof(TestUserControl), new PropertyMetadata(0));
}
public TestUserControl()
{
InitializeComponent();
}
public int num
{
get { return (int)GetValue(numProperty); }
set { SetValue(numProperty, value); }
}
// Using a DependencyProperty as the backing store for num. This enables animation, styling, binding, etc...
public static readonly DependencyProperty numProperty =
DependencyProperty.Register("num", typeof(int), typeof(TestUserControl), new PropertyMetadata(0));
}
という感じ
DataContext に Binding するとしたら この num と TextBox などのコントロールのプロパティを Binding することになります
通常は DataContext 用の (ViewModel となる) クラスを作って そこをソースとして Binding するのですが この場合 Binding のソースにしたい num は TestUserControl のプロパティです
DataContext を使うなら
this.DataContext = this;
になります
あまり this を DataContext にしたくないので 別の方法にしたいです
他の方法だと SetBinding を使ってコード側でひとつひとつ Binding を書いていくことができます
これだと Source に this を設定しますが その Binding のプロパティのみに使われるので 問題が起きることもなさそうです
でもこれって結構面倒ですし XAML の良さがなくなるように思います
デフォルトの UserControl って本当にこうやって作られてるの??
目指すは TextBox などの組み込みの UserControl と同じ感じに使えるものなのでとりあえず framework のソースを見てみるのが一番です
https://referencesource.microsoft.com/
いくつかコントロールを見ましたが どれもコードが長いです
シンプルで読みやすいのを探してるのですけどねー
WPF は WinForms と違ってデフォルトコントロールは少なめです
内部に TextBox を持っていて動きもシンプルそうな NumericUpDown でもあればイメージが掴めそうなのにないんです
とりあえず ComboBox や DatePicker や PasswordBox あたりを流し見した感じ DataContext は使って無くて一部スタイルぽいところを SetBinding してるくらいです
内部で TextBox のインスタンスを持っていて 変更イベント時に何かして と WinForms とあんまり変わらない感じの作りのようです
XAML で書くとめったに x:Name をつけないので UserControl や Window からコントロールにアクセスすることはほとんどないですが デフォルトコントロールの作りでは直接コントロールアクセスしてる感じです
WPF は MVVM だー なんて言われてますが内部実装はそうでもないのですね
「デフォルトコントロールみたいに使えるユーザコントロール作りたいけど MVVM でどうすればいいかわからなーい」 という疑問の答えは 作り方が違う です
UserControl 作るときは DataContext を持たずに デフォルトコントロールに近い感じで作っておいたほうが 使い勝手も近くなりますし VM ぽいことをしないのもありかなって思います
普段書く 何か目的のものを作るコードは 見やすさや変更が楽にできることを重視で 速度はそれほどこだわらないけど ライブラリを作る場合はムダを削って速度が出来る限り遅くないようにしたい というのに近いかも