げんさん日記

プログラミングで気付いた事等を書きます。

指定された名前のコントロールにフォーカスを設定します。

2019年11月06日 08時41分48秒 | WPF
画面内にContentControl等が存在しても表示時のコントロールにフォーカスが当たるようにする方法を記します。
コントロールの一覧を取得する方法としてはLogicalTreeHelperとVisualTreeHelperで行う方法がありますが、LogicalTreeHelperではContentControlの内容まで検索されませんでしたのでVisualTreeHelperを使用しコントロールにフォーカスを設定します。

拡張プロパティを用意します。
public static void SetFocus(this DependencyObject parentControl, string setFocusControlName)
{
  // 子コントロールを全て取得し、コントロールの数分繰り返します。
  for (int i = 0; i
  {
    // 子コントロールを取得します。
    DependencyObject childObj = VisualTreeHelper.GetChild(parentControl, i);

    // 該当のコントロールかチェックします。
    if (childObj is FrameworkElement &&
      ((FrameworkElement)childObj).Name == setFocusControlName)
    {
      // 該当コントロールの場合はフォーカスを設定します。
      ((FrameworkElement)childObj).Focus();
      return;
    }

    // 対象コントロールに子コントロールが存在する場合は、再帰処理を行います。
    if (VisualTreeHelper.GetChildrenCount(childObj) > 0)
    {
      SetFocus(childObj, setFocusControlName);
    }
  }
}

使用例
public abstract class MainWindow : Window
{
  public void OnSetFocus(string controlName)
  {
    // コントロールにフォーカスを設定する。
    this.SetFocus(controlName);
  }
}
上記はコードビハインドでの使用例です。コントロール名はXamlのName属性です。