WPF 在运行时设置键盘焦点,无需代码

标签 wpf xaml mvvm

我在该主题上进行了很多搜索,但在没有代码的情况下无法真正找到解决方案。我知道有些人会说为这个 View 相关的事情使用代码隐藏是完全可以的,但我还是想避免它。

我有一个用户控件,它显示一个带有单个文本框和一个确定按钮的“对话框”。该对话框是一个简单的用户控件,位于所有其他控件之上。默认情况下,用户控件的可见性设置为折叠。如果用户控件可见,我想将键盘焦点设置为对话框用户控件上的文本框。有没有办法在 xaml 中完全做到这一点?由于在加载控件时我的对话框控件不可见,因此只需设置
FocusManager.FocusedElement="{Binding ElementName=tbID}"
不管用。我尝试使用某种可见性触发器:

   <TextBox Grid.Column="3"
             Grid.Row="5"
             Name="tbID"
             VerticalAlignment="Center">
        <TextBox.Style>
            <Style TargetType="{x:Type TextBox}">
                <Style.Triggers>
                    <Trigger Property="Visibility" Value="Visible">
                        <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=tbID}" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </TextBox.Style>
    </TextBox>

但这也不起作用。触发器被触发,但文本框没有获得焦点。我真的很感激对此的任何建议。提前致谢!

最佳答案

您可以尝试使用附加行为来设置焦点。这是一些示例代码:

public static class Focus
{
    public static readonly DependencyProperty ShouldFocusWhenVisibleProperty =
        DependencyProperty.RegisterAttached("ShouldFocusWhenVisible", typeof (bool), typeof (Focus), new PropertyMetadata(default(bool), ShouldFocusWhenVisibleChanged));

    private static void ShouldFocusWhenVisibleChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        var uiElement = sender as UIElement;
        if (uiElement == null) return;

        var shouldFocus = GetShouldFocusWhenVisible(uiElement);
        if (shouldFocus)
        {
            UpdateFocus(uiElement);
            uiElement.IsVisibleChanged += UiElementOnIsVisibleChanged;
        }
        else
            uiElement.IsVisibleChanged -= UiElementOnIsVisibleChanged;
    }

    private static void UiElementOnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var uiElement = sender as UIElement;
        if (uiElement == null) return;

        UpdateFocus(uiElement);
    }

    private static void UpdateFocus(UIElement uiElement)
    {
        if (!uiElement.IsVisible) return;

        Keyboard.PrimaryDevice.Focus(uiElement);
    }

    public static void SetShouldFocusWhenVisible(UIElement uiElement, bool value)
    {
        uiElement.SetValue(ShouldFocusWhenVisibleProperty, value);
    }

    public static bool GetShouldFocusWhenVisible(UIElement uiElement)
    {
        return (bool)uiElement.GetValue(ShouldFocusWhenVisibleProperty);
    }
}

然后,将以下代码应用到对话框中的 TextBox:<TextBox local:Focus.ShouldFocusWhenVisible="True" /> .请注意 local:将需要是对上述 Focus 类的命名空间的引用。

关于WPF 在运行时设置键盘焦点,无需代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15200793/

相关文章:

wpf - 如何绑定(bind)到 WPF 中两个数据绑定(bind)值的总和?

c# - 是否有必要为简单的 true/false 操作创建一个转换器?

c# - MVVM 和自定义命令?

wpf - 可观察集合项的更改未反射(reflect)在数据网格中

c# - ListViewItem MouseDoubleClick MVVM方式

c# - 寻找 C++ 到 WPF/Cocoa 互操作性的跨平台、端到端示例

wpf - 单独的XAML中的TabItem

android - 是否可以添加通过单击 Android 中的按钮调用的方法(不添加监听器)

c# - XAML 键绑定(bind) 1,2,3

xaml - 如何链接 View 和 ViewModel 以及在哪里创建它们