views:

4005

answers:

2

In an application I'm working on, we have a bunch of custom controls with their ControlTemplates defined in Generic.xaml.

For instance, our custom textbox would look similar to this:

<Style TargetType="{x:Type controls:FieldTextBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type controls:FieldTextBox}">
                <Border BorderThickness="0" Margin="5">
                    <StackPanel ToolTip="{Binding Path=Field.HintText, RelativeSource={RelativeSource TemplatedParent}}">
                        <TextBlock Text="{Binding Path=Field.FieldLabel, RelativeSource={RelativeSource TemplatedParent}}" 
                                   HorizontalAlignment="Left" 
                                   />
                        <TextBox Width="{Binding Path=Field.DisplayWidth, RelativeSource={RelativeSource TemplatedParent}}" 
                                 HorizontalAlignment="Left" 
                                 Text="{Binding Path=Field.Data.CurrentValue, RelativeSource={RelativeSource TemplatedParent}}" 
                                 IsEnabled="{Binding Path=Field.IsEnabled, RelativeSource={RelativeSource TemplatedParent}}"
                                 ContextMenu="{Binding Source={StaticResource FieldContextMenu}}" >
                            <TextBox.Background>
                                <SolidColorBrush Color="{Binding Path=Field.CurrentBackgroundColor, RelativeSource={RelativeSource TemplatedParent}}"/>
                            </TextBox.Background>
                        </TextBox>
                    </StackPanel>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Focusable" Value="True" />
    <Setter Property="IsTabStop" Value="False" />
</Style>

In our application, we need to be able to programatically set the focus on a particular control within the ControlTemplate.

Within our C# code, we can get to the particular "FieldTextBox" based on our data. Once we have the correct FieldTextBox, we need to be able to set the focus on the actual TextBox contained within the ControlTemplate.

The best solution I've come up with is to set a name on the primary control in each control template (in this case it's the TextBox), such as "FocusableControl."

My code (contained in the code-behind for the FieldTextBox) to then set focus on the control would be:

    Control control = (Control)this.Template.FindName("FocusableControl", this);
    if (control != null)
    {
        control.Focus();
    }

This solution works. However, does anyone else know of a solution that would be more efficient than this?

+1  A: 

Within your control template you can add a Trigger that sets the FocusedElement of the StackPanel's FocusManager to the textbox you want focused. You set the Trigger's property to {TemplateBinding IsFocused} so it fires when the containing control is focused.

Will
TemplateBinding isn't needed for the ControlTemplate's trigger. Simply set the trigger's property to "IsFocused." The solution works, however I'm not sure if it's really more efficient.
Bob
A: 

You can get rid of the hard coding of control name in the code by providing some DependancyProperty and have the same code in controlLoaded or OnApplyTemplate function based on the DependancyProperty. This DependancyProperty's sender will the candidate for .Focus() call.

Jobi Joy
I'm not sure if I entirely understand your solution. Could you be more clear or give a short example?
Bob