将焦点设置为可见的用户控件 [英] Set focus to a usercontrol when it is made visible

查看:221
本文介绍了将焦点设置为可见的用户控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我显示一个 MessageBox ,并希望用户能够使用 CTRL + C 。问题是我似乎无法将焦点设置为对话框。

I am showing a MessageBox and want the user to be able to copy the contents of the message using CTRL+C. The problem is that I can't seem to set focus to the dialog.

MessageBox 在MVVM中实现。要显示它,我只是让用户控件可见(中心屏幕)并禁用主视图。

The MessageBox is implemented in MVVM. To show it I just make a usercontrol visible (centre screen) and disable the main view.

复制命令使用Prism DelegateCommand实现:

The copy command is implemented using a Prism DelegateCommand:

<UserControl.InputBindings>
    <KeyBinding Key="C" Modifiers="Control" Command="{Binding CopyCommand}"/>
</UserControl.InputBindings>

如果我打开消息框按钮,CopyCommand就会触发。但是,在显示对话框时,我无法让它开始工作。

If I tab onto on of the message box button the CopyCommand fires. However I cannot get it to work initially when the dialog is shown.

如何让用户控件接受焦点或将KeyBinding附加到整个用户控件?

How do I get the usercontrol to accept focus or to attach the KeyBinding to the whole of the usercontrol?

注意: 我需要一个MVVM解决方案,因为不需要任何代码

Note: I need an MVVM solution as don't want any code in the code behind file.

推荐答案

在使用MVVM模式并需要与用户界面交互的情况下,我总是试图实现此解决方案通过附加行为。附加行为是非常强大和方便的解决方案,完全满足MVVM模式,也可以在Blend(使用预定义接口)中使用。

In situations when using MVVM pattern and need to interact with the user interface, I always try to implement this solution through an attached behavior. Attached behavior is very powerful and convenient solution that fully satisfies the MVVM pattern, which can also be used in the Blend (with a pre-defined interface).

在这种情况下,我创建了一个附加行为 VisibleFocusBehavior ,它设置了 IsVisibleChanged 事件处理程序,其中在元素的可见性的情况下设置焦点。

In this case, I created an attached behavior VisibleFocusBehavior, which set a IsVisibleChanged event handler, wherein the focus is set in the case of the visibility of the element.

为避免出现虚线框,当控件获得焦点时,我设置 FocusVisualStyle ={x:Null} for UserControl。

To avoid the appearance of dotted box, when the control gets focus, I set FocusVisualStyle="{x:Null} for UserControl.

VisibleFocusBehavior

VisibleFocusBehavior

public class VisibleFocusBehavior
{
    #region IsFocusEnabled Dependency Property

    public static readonly DependencyProperty IsFocusEnabledProperty;

    public static void SetIsFocusEnabled(DependencyObject DepObject, bool value)
    {
        DepObject.SetValue(IsFocusEnabledProperty, value);
    }

    public static bool GetIsFocusEnabled(DependencyObject DepObject)
    {
        return (bool)DepObject.GetValue(IsFocusEnabledProperty);
    }

    #endregion

    #region BringToFrontBehavior Constructor

    static VisibleFocusBehavior()
    {
        IsFocusEnabledProperty = DependencyProperty.RegisterAttached("IsFocusEnabled",
                                                            typeof(bool),
                                                            typeof(VisibleFocusBehavior),
                                                            new UIPropertyMetadata(false, IsFocusTurn));
    }

    #endregion

    #region IsFocusTurn

    private static void IsFocusTurn(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        UIElement element = sender as UIElement;

        if (e.NewValue is bool && ((bool)e.NewValue) == true)
        {
            if (element != null)
            {
                element.IsVisibleChanged += new DependencyPropertyChangedEventHandler(ElementIsVisibleChanged);
            }
        }
    }

    #endregion

    #region ElementIsVisibleChanged Handler

    private static void ElementIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) 
    {
        UIElement visibilityElement = sender as UIElement;

        if (visibilityElement.IsVisible == true) 
        {
            visibilityElement.Focus();
        }
    }

    #endregion
}


$ b b

使用 示例

Example of using

<UserControl x:Class="UserControlFocusHelp.TestUserControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:UserControlFocusHelp"             
         mc:Ignorable="d" 
         d:DesignHeight="300" 
         d:DesignWidth="300"
         xmlns:AttachedBehaviors="clr-namespace:UserControlFocusHelp.AttachedBehaviors"
         AttachedBehaviors:VisibleFocusBehavior.IsFocusEnabled="True"
         FocusVisualStyle="{x:Null}">

<UserControl.InputBindings>
    <KeyBinding Key="C" 
                Modifiers="Control"
                Command="{Binding CopyCommand}" />
</UserControl.InputBindings>

测试视窗

Test window

XAML

<Grid>
    <local:TestUserControl x:Name="TestUserControl"
                           Width="300"
                           Height="300"
                           Focusable="True"
                           Visibility="Collapsed" />

    <Button Width="100"
            Height="30" 
            Content="Visible" 
            HorizontalAlignment="Left"
            Click="Button_Click" />
</Grid>

代码隐藏

private void Button_Click(object sender, RoutedEventArgs e)
{
    TestUserControl.Visibility = Visibility.Visible;
}




完整示例在链接

这篇关于将焦点设置为可见的用户控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆