webentwicklung-frage-antwort-db.com.de

WPF - Entfernt den Fokus, wenn Sie außerhalb eines Textfelds klicken

Ich habe einige Textfelder, in denen ich möchte, dass sich der Fokus ein wenig anders als normal für eine WPF-Anwendung verhält. Grundsätzlich möchte ich, dass sie sich eher wie eine Textbox auf einer Webseite verhalten. Das heißt, wenn ich irgendwo außerhalb des Textfelds klicke, verliert es seinen Fokus. Was ist der beste Weg, dies zu tun?

Wenn die Antwort darin besteht, den Fokus programmgesteuert zu entfernen, wie kann ein Mausklick außerhalb der Grenzen am besten erkannt werden? Was ist, wenn das Element, auf das ich klicke, der neue Empfänger von focus ist?

22
JacobJ

Anstatt dem Fenster ein neues Steuerelement hinzuzufügen, denke ich, Sie sollten Ihrem Grid einen Namen geben und auf das MouseDown -Ereignis in Ihrem Fenster reagieren, wobei der Fokus auf das Grid sich selbst verschoben wird. Etwas wie das: 

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="412" Width="569" MouseDown="Window_MouseDown" Name="window1" >
    <Grid ShowGridLines="False" KeyDown="Grid_KeyDown" Name="grid1" Focusable="True">
          <TextBox HorizontalAlignment="Left" Margin="117,61,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
    </Grid>
</Window>

code hinter:

private void window1_MouseDown(object sender, MouseButtonEventArgs e)
{
    grid1.Focus();
}
26

Ich denke, ein besserer Weg, um dieses Problem zu lösen, ist das Hinzufügen eines MouseDown-Ereignishandlers zu einem Fenster mit dahinterliegendem Code:

private void window_MouseDown(object sender, MouseButtonEventArgs e)
{
    Keyboard.ClearFocus();
}
12
NightEagle

Eine andere Methode, die für mich funktionierte, war die Verwendung

Mouse.AddPreviewMouseDownOutsideCapturedElementHandler

Angenommen, Sie hatten einen TextBlock, der beim Klicken bearbeitbar werden sollte, indem eine fokussierte TextBox angezeigt wird. Wenn der Benutzer dann außerhalb der Textbox klickte, sollte er wieder ausgeblendet werden. So kannst du es machen:

private void YourTextBlock_OnMouseDown(object sender, MouseButtonEventArgs e)
{
    YourTextBox.Visibility = Visibility.Visible;
    YourTextBox.Focus();
    CaptureMouse();
    Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, OnMouseDownOutsideElement);
}

private void OnMouseDownOutsideElement(object sender, MouseButtonEventArgs e)
{
    Mouse.RemovePreviewMouseDownOutsideCapturedElementHandler(this, OnMouseDownOutsideElement);
    ReleaseMouseCapture();
    YourTextBox.Visibility = Visibility.Hidden;
}
3
Mr. Bungle

Ich bin nicht zu 100% sicher, aber wenn Sie Focusable für das Containerelement (Grid, StackPanel usw.) auf "true" setzen, sollte der Fokus vom Textfeld genommen werden.

2
Richard Szalay

Wenn Sie auf das Element geklickt haben, das den Fokus erfassen kann, erhalten Sie das, was Sie brauchen. Wenn Sie beispielsweise über ein Bedienfeld verfügen, können Sie das mouseClick-Ereignis des Bedienfelds bearbeiten, um Ihre Anforderungen zu erfüllen, oder den Rat von Richard Szalay verwenden.

1
stukselbax

Um Code hinter dem Code zu vermeiden, können Sie dieses Verhalten verwenden Das Verhalten

 public class ClearFocusOnClickBehavior : Behavior<FrameworkElement>
 {
    protected override void OnAttached()
    {
        AssociatedObject.MouseDown += AssociatedObject_MouseDown;
        base.OnAttached();
    }

    private static void AssociatedObject_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        Keyboard.ClearFocus();
    }

    protected override void OnDetaching()
    {
        AssociatedObject.MouseDown -= AssociatedObject_MouseDown;
    }
}

Verwendung in XAML:

Bei einem beliebigen Element außerhalb des Textfelds, in dem er den Fokus auf "Löschen" löschen soll, klicken Sie auf "Hinzufügen":

    <i:Interaction.Behaviors>
        <behaviors:ClearFocusOnClickBehavior/>
    </i:Interaction.Behaviors>
1
shmoltz
public class ClearFocusOnOutsideClickBehavior : Behavior<FrameworkElement>
{
    protected override void OnAttached()
    {

        AssociatedObject.GotFocus += AssociatedObjectOnGotFocus;
        AssociatedObject.LostFocus += AssociatedObjectOnLostFocus;
        base.OnAttached();
    }

    private void AssociatedObjectOnLostFocus(object sender, RoutedEventArgs e)
    {
        App.Current.MainWindow.MouseUp -= _paren_PreviewMouseUp;
    }

    private void AssociatedObjectOnGotFocus(object sender, RoutedEventArgs e)
    {
        App.Current.MainWindow.MouseUp += _paren_PreviewMouseUp;
    }

    private void _paren_PreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
        Keyboard.ClearFocus();
    }

    protected override void OnDetaching()
    {
        AssociatedObject.GotFocus -= AssociatedObjectOnGotFocus;
        AssociatedObject.LostFocus -= AssociatedObjectOnLostFocus;
    }
}

Verwendung in XAML:

<TextBox Height="30" Width="200">
            <i:Interaction.Behaviors>
                <behaviours:ClearFocusOnOutsideClickBehavior/>
            </i:Interaction.Behaviors>
 </TextBox>
0
Slavik Glodan

Ich habe die ausgewählte Antwort in reaktiver WPF-Anwendung ausprobiert, sie löste jedoch nicht den Fokus des Textfelds aus, aufgrund dessen das Textfeld nicht den Fokus verlor. Folgende Lösung funktioniert für mich.

Verknüpfen Sie ein Mouse-Down-Ereignis mit Window:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="412" Width="569" MouseDown="window_MouseDown" Name="window1" >
    <Grid ShowGridLines="False" KeyDown="Grid_KeyDown" Name="grid1" Focusable="True">
          <TextBox HorizontalAlignment="Left" Margin="117,61,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
    </Grid>
</Window>

und Veranstaltung ist:

private void window_MouseDown(object sender, MouseButtonEventArgs e)
{
    TextBox textBox = Keyboard.FocusedElement as TextBox;
    if (textBox != null)
    {
        TraversalRequest tRequest = new TraversalRequest(FocusNavigationDirection.Next);
        textBox.MoveFocus(tRequest);
    }
}
0
Zaheer Ahmed

Sie können das Ereignis IsKeyboardFocusedChanged verwenden:

myTextBox.IsKeyboardFocusedChanged += myTextBox_IsKeyboardFocusedChanged;

private void SendFileCaptionTextBox_IsKeyboardFocusedChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if (e.NewValue.ToString() == "True")
    {
        // it's focused
    }
    else
    {
        // it's not focused
    }
}    
0
Mayer Spitzer

sie können den Fokus eines Steuerelements nicht explizit verlieren

sie können stattdessen den Fokus auf andere Steuerelemente setzen

**txt.Focusable=true;
label.focus();
Keyboard.Focus(txtPassword);**

versuche dies

0
user3060599

Ich hatte ein ähnliches Problem, aber als ich meine Textboxen um ein ScrollViewer-Steuerelement wickelte, verloren alle Textboxen automatisch den Fokus, wenn Sie auf eine Stelle außerhalb der Texboxen klicken.

0