【问题标题】:Setting Focus on a Control within a ControlTemplate in WPF在 WPF 中的 ControlTemplate 中将焦点设置在控件上
【发布时间】:2010-09-14 14:02:21
【问题描述】:

在我正在开发的应用程序中,我们有一堆自定义控件,它们的 ControlTemplate 定义在 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();
    }

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

【问题讨论】:

    标签: c# .net wpf xaml controls


    【解决方案1】:

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

    【讨论】:

    • ControlTemplate 的触发器不需要TemplateBinding。只需将触发器的属性设置为“IsFocused”。该解决方案有效,但我不确定它是否真的更有效。
    • 如果您能详细说明您的解决方案,我们可能会在此处获得可接受的答案。我正在尝试做类似的事情,并且正在尝试您的建议,但我并没有完全遵循触发器的值绑定在其他细节中的样子。
    【解决方案2】:

    您可以通过提供一些 DependancyProperty 来摆脱代码中控件名称的硬编码,并在基于 DependancyProperty 的 controlLoaded 或 OnApplyTemplate 函数中具有相同的代码。 此 DependancyProperty 的发件人将成为 .Focus() 调用的候选者。

    【讨论】:

    • 我不确定我是否完全理解您的解决方案。您能否说得更清楚些或举个简短的例子?
    猜你喜欢
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 2011-06-09
    • 1970-01-01
    • 2011-03-21
    • 1970-01-01
    相关资源
    最近更新 更多