ちょっとした覚書。 TemplateからNameを元にコントロールを探すにはControlTemplate.FindNameメソッドまたはFrameworkElement.GetTemplateChildメソッドを使うようです。 FrameworkElement.FindNameメソッドはTemplateの中までは探してくれないらしい。 参考サイトはこちら。
1つのTemplateが複数のコントロールに適用された場合、同じNameのコントロールがその数だけ作成されます。 なのでNameでコントロールを探すときはVisualTreeHelperを使うのではなく、名前スコープを考慮したこれらのメソッドを使うものなんだそうです。 気付くのに遅れて無駄足を踏んでしまった...
メソッドということでxamlからは使用できません。
使用例はこんな感じ。
public class CustomControl1 : Button { private Label _hoge; public CustomControl1() { Loaded += OnLoaded; } private void OnLoaded(object sender, RoutedEventArgs e) { Updateなんたら(); } protected override void OnTemplateChanged(ControlTemplate oldTemplate, ControlTemplate newTemplate) { if (IsLoaded) Updateなんたら(); } private void Updateなんたら() { // カスタムコントロール内で使えるprotectedメソッド Button foo = this.GetTemplateChild("foo") as Button; // カスタムコントロールではない場合はこちらを使う Border bar = _hoge.Template.FindName("bar", _hoge) as Border; } }
インスタンス化してからしか使えないのでこうなります。 カスタムコントロールのOnTemplateChangedメソッドはLoadedイベントの前に呼ばれるため、IsLoadedでインスタンスがあるかどうかを判断します。
どうでもいいけど、名前空間と名前スコープって紛らわしいですよね? そうでもない?