在WPF中将焦点设置在ControlTemplate中的控件上

时间:2008-10-01 16:35:43

标签: c# .net wpf xaml controls

在我正在处理的应用程序中,我们有一堆自定义控件,其ControlTemplates在Generic.xaml中定义。

例如,我们的自定义文本框看起来与此类似:

<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>

在我们的应用程序中,我们需要能够以编程方式将焦点放在ControlTemplate中的特定控件上。

在我们的C#代码中,我们可以根据我们的数据访问特定的“FieldTextBox”。一旦我们有了正确的FieldTextBox,我们就需要能够将焦点设置在ControlTemplate中包含的实际TextBox上。

我提出的最佳解决方案是在每个控件模板的主控件上设置一个名称(在本例中为TextBox),例如“FocusableControl”。

我的代码(包含在FieldTextBox的代码隐藏中)然后将焦点设置在控件上:

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

此解决方案有效。但是,是否有其他人知道一种比这更有效的解决方案?

2 个答案:

答案 0 :(得分:2)

在控件模板中,您可以添加一个Trigger,将StackPanel的FocusManager的FocusedElement设置为您想要关注的文本框。您将Trigger的属性设置为{TemplateBinding IsFocused},以便在关注包含控件时触发。

答案 1 :(得分:0)

您可以通过提供一些DependancyProperty来消除代码中控件名称的硬编码,并在基于DependancyProperty的controlLoaded或OnApplyTemplate函数中使用相同的代码。 这个DependancyProperty的发送者将成为.Focus()调用的候选者。