Установка фокуса на элемент управления в шаблоне ControlTemplate (часть 2)

Я не понимаю, что должно быть одним из наиболее распространенных требований WPF. Я прочитал этот вопрос, но моя реализация решения не работает.

Вот разметка элемента управления без внешнего вида:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:WpfTest">
  <Style TargetType="{x:Type local:CustomControl}">
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type local:CustomControl}">
          <Border>
            <TextBox x:Name="myTextBox" />
          </Border>
          <ControlTemplate.Triggers>
            <Trigger Property="IsFocused"
                     Value="True">
              <Setter Property="FocusManager.FocusedElement"
                      Value="{Binding ElementName=myTextBox}" />
              <Setter TargetName="myTextBox"
                      Property="Background"
                      Value="Green" />
            </Trigger>
          </ControlTemplate.Triggers>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</ResourceDictionary>

Вот разметка окна, содержащего экземпляр CustomControl:

<Window x:Class="WpfTest.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfTest"
        Title="Window1" Height="300" Width="300">

  <local:CustomControl x:Name="CCtl" />
</Window>

А вот код программной части:

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
        Loaded += (RoutedEventHandler)delegate { CCtl.Focus(); };
    }
}

Когда Window1 загружен, текстовое поле становится зеленым (указывая, что триггер работает), но фокус остается с CCtl, а не с текстовым полем. Несомненно, это связано с выводом, отображающим следующую ошибку данных:

Не удается найти источник привязки со ссылкой "ElementName = myTextBox". BindingExpression: (нет пути); DataItem = null; целевой элемент - CustomControl (Name = 'CCtl'); целевым свойством является FocusedElement (тип IInputElement).

Понятия не имею, почему появляется эта ошибка. Любые указатели с благодарностью получены, спасибо.


person Chris Ward    schedule 01.12.2010    source источник


Ответы (2)


Попробуйте вместо этого использовать это для своего триггера:

<Trigger Property="IsFocused" Value="True">
    <Setter TargetName="myTextBox" Property="FocusManager.FocusedElement" Value="{Binding ElementName=myTextBox}" />
</Trigger>

Ошибка сообщает вам, что он не может найти myTextBox, потому что имя не входит в область действия, к которой применяется свойство FocusedElement. В данном случае это сам экземпляр CCtl, который не может видеть внутри своего собственного шаблона. Установив свойство для чего-то внутри шаблона, Binding может найти названный элемент.

person John Bowen    schedule 01.12.2010

Возможно, я ошибаюсь, но я думаю, что ваша проблема связана с триггером свойства.

Установив свой TextBox на фокусировку, вы фактически аннулируете Trigger на шаблонном родительском элементе, поэтому триггер разворачивается и меняет направление установки фокуса на TextBox (следовательно, не фокусируя его).

person Dean Chalk    schedule 01.12.2010