ちょっとした覚書。 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でインスタンスがあるかどうかを判断します。
どうでもいいけど、名前空間と名前スコープって紛らわしいですよね? そうでもない?

