Andrue Cope
Andrue Cope

Reputation: 249

WPF setting focus to control within control template

I have the following ControlTemplate:

    <ControlTemplate TargetType="dxe:TextEdit" x:Key="TextEditMultiStyle">
    <Border x:Name="border" BorderBrush="#054c74" BorderThickness="1" CornerRadius="1">
        <Border.Effect>
            <DropShadowEffect ShadowDepth="0" Color="#0980c2" Opacity="1" BlurRadius="5" />
        </Border.Effect>
        <dxe:TextEdit x:Name="textEdit" TextWrapping="Wrap" AcceptsReturn="True" Text="{TemplateBinding Text}" BorderThickness="0"
                      EditValue="{Binding RelativeSource={RelativeSource TemplatedParent}, 
                          Path=EditValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
                      VerticalContentAlignment="Top"/>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsFocused" Value="true">
            <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=textEdit}"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

I have added a TextBox to my window and now want to set focus to it when the window loads. Nothing has worked so far and I believe it's because I need to set focus to the TextEdit within my ControlTemplate. That's what the Trigger is supposed to be doing.

Unfortunately I cannot work out what I should specify as the trigger. The above code just gives a runtime complaint:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=textEdit'. BindingExpression:(no path); DataItem=null; target element is 'TextEdit' (Name='MarkerTextEdit'); target property is 'FocusedElement' (type 'IInputElement')

I'm also not convinced that the trigger would set the property on the correct FocusManager anyway as I think I need to set it on the Window's FocusManager.

So I think I need something equivalent to:

(pseudo code) FindAncestor(Window).FocusManager.FocusedElement=ControlTemplate.Controls('textEdit')

If that makes any sense.

Any suggestions are welcome because all I want to do is have my TextBox get the focus when the window loads. Something that's stupidly easy in WinForms but appears to be rocket science in WPF.

Update:I think I've confirmed my theory as the following Code-behind works:

private void MarkerEditorWindow_Loaded(object sender, RoutedEventArgs e)
    {
        var control = (UIElement)MarkerTextEdit.Template.FindName("textEdit", MarkerTextEdit);

        control.Focus();
    }

Upvotes: 0

Views: 2182

Answers (1)

Andrue Cope
Andrue Cope

Reputation: 249

The solution is to change the trigger to:

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

Interestingly this also causes the TextEdit to be focused even if I don't put anything in the XAML or code-behind to cause it. It looks as though WPF has been trying to do that all along but was thwarted by my template.

Upvotes: 2

Related Questions