简体   繁体   English

如何在文本框中限制焦点

[英]How to restrict focus in textbox

I have a dialog with few controls. 我有一个带有少量控件的对话框。 There is a TextBox named txtControl and two Buttons Accept and Cancel . 有一个名为txtControlTextBox和两个Buttons AcceptCancel I want that once the focus is in txtControl , the focus should not go away, until I click on Accept or Cancel button. 我希望一旦焦点位于txtControl中 ,焦点就不会消失,直到我单击“ 接受”或“ 取消”按钮。

If I try to click on any other control without clicking on Accept or Cancel button, then focus should remains in txtControl . 如果我尝试单击任何其他控件而不单击“ 接受”或“ 取消”按钮,则焦点应保留在txtControl中 Also I don't want to disable or gray out other controls. 另外我也不想禁用或禁用其他控件。

You might handle OnPreviewMouseDown in the root, whenever focus is on txtControl, and the mouse is not over txtControl, Accept or Cancel; 每当焦点位于txtControl上并且鼠标不在txtControl上方时,您都可以在根目录中处理OnPreviewMouseDown;请单击Accept或Cancel。

void mainWindow_previewMouseDown(object sender, MouseEventArg e)
{

     if (txtControl.IsFocusWithin)         
     {
          if (txtControl.IsMouseOver == false ||
             accept.IsMouseOver ==false ||
             cancel.IsMouseOver ==false)
          {
              e.Handle = true;
          }
      }
}

and you might also hadle PreviewKeyDown to see if Tab is Pressed or not. 并且您可能还需要PreviewKeyDown来查看是否已按下Tab键。

This kind of restriction is not a good idea. 这种限制不是一个好主意。

How will your app be used by someone who can't use a mouse and uses the tab key to move between controls? 无法使用鼠标并使用Tab键在控件之间移动的人将如何使用您的应用程序?

You could handle the PreviewLostKeyboardFocus at root level. 您可以在根级别处理PreviewLostKeyboardFocus

In xaml 在xaml中

<Window ... PreviewLostKeyboardFocus="Win_PreviewLostKeyboardFocus">

In C# 在C#中

private void Win_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        // change focus behavior only when txtControl 
                          // is the element losing focus
        if (e.OldFocus != txtControl)
            return;

                          // if new element with focus is not Accept and is not Cancel, then disable the focus change
        if (e.NewFocus != Accept && e.NewFocus != Cancel)
            e.Handled = true;
    }

I would create an attached property that looked for the textbox losing Keyboad focus and just force focus back in to the textbox again. 我将创建一个附加属性,该属性用于查找失去键盘提示焦点的文本框,然后再次将焦点重新强制回到文本框。

The attached property would be something like this. 附加的属性将是这样的。

  public class TextBoxExtras : DependencyObject
    {
        public static bool GetRetainsFocus(DependencyObject obj)
        {
            return (bool)obj.GetValue(RetainsFocusProperty);
        }

        public static void SetRetainsFocus(DependencyObject obj, bool value)
        {
            obj.SetValue(RetainsFocusProperty, value);
        }

        public static readonly DependencyProperty RetainsFocusProperty =
            DependencyProperty.RegisterAttached("RetainsFocus", typeof(bool), typeof(TextBoxExtras), new PropertyMetadata(false, new PropertyChangedCallback((s, e) =>
                {
                    TextBox textBox = s as TextBox;
                    if (textBox != null)
                    {
                        if (!(bool)e.NewValue && (bool)e.OldValue)
                            textBox.LostKeyboardFocus -= textBox_LostKeyboardFocus;
                        if ((bool)e.NewValue)
                        {
                            textBox.LostKeyboardFocus += textBox_LostKeyboardFocus;
                            textBox.Unloaded += textBox_Unloaded;
                        }
                    }
                })));

        static void textBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (textBox != null )
                if (textBox.Focusable)
                    textBox.Focus();
        }

        static void textBox_Unloaded(object sender, RoutedEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (textBox != null)
            {
                textBox.LostKeyboardFocus -= textBox_LostKeyboardFocus;
                textBox.Unloaded -= textBox_Unloaded;
            }
        }
    }

And use it in XAML like this, the first textbox is the one that will "retain focus" 像这样在XAML中使用它,第一个文本框是“保持焦点”的文本框

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication4"
        Background="Black"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBox local:TextBoxExtras.RetainsFocus="True" Margin="10,10,387,283"/>        
        <TextBox HorizontalAlignment="Left" Height="23" Margin="10,37,0,260" Width="120" />
        <Button Content="Accept" HorizontalAlignment="Left" Margin="10,81,0,0" VerticalAlignment="Top" Width="75" />
    </Grid>
</Window>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM