Wpf - Set Focus When a Button Is Clicked - No Code Behind

WPF - Set Focus when a button is clicked - No Code Behind

Have you considered using an attached behaviour. They are simple to implement and use AttachedProperty's. Although it still requires code, this code is abstracted away in a class and be reused. They can eliminate the need 'code behind' and are often used with the MVVM pattern.

Try this one and see if it works for you.

public class EventFocusAttachment
{
public static Control GetElementToFocus(Button button)
{
return (Control)button.GetValue(ElementToFocusProperty);
}

public static void SetElementToFocus(Button button, Control value)
{
button.SetValue(ElementToFocusProperty, value);
}

public static readonly DependencyProperty ElementToFocusProperty =
DependencyProperty.RegisterAttached("ElementToFocus", typeof(Control),
typeof(EventFocusAttachment), new UIPropertyMetadata(null, ElementToFocusPropertyChanged));

public static void ElementToFocusPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var button = sender as Button;
if (button != null)
{
button.Click += (s, args) =>
{
Control control = GetElementToFocus(button);
if (control != null)
{
control.Focus();
}
};
}
}
}

And then in your XAML do something like...

<Button 
Content="Click Me!"
local:EventFocusAttachment.ElementToFocus="{Binding ElementName=textBox}"
/>
<TextBox x:Name="textBox" />

Set focus to another element with default button event?

Do the focusing in the Button's Click event. It'll get called when you press Enter, too.

<Button IsDefault="True" Content="Process Test File" 
Command="{Binding ProcessFileCommand, UpdateSourceTrigger=PropertyChanged}"
Click="Button_Click">
</Button>

Then, in code-behind:

private void Button_Click(object sender, RoutedEventArgs e)
{
Keyboard.Focus(txtClientId);
}

Set focus on TextBox in WPF from view model

Let me answer to your question in three parts.

  1. I'm wondering what is "cs.txtCompanyID" in your example? Is it a TextBox control? If yes, then you are on a wrong way. Generally speaking it's not a good idea to have any reference to UI in your ViewModel. You can ask "Why?" but this is another question to post on Stackoverflow :).

  2. The best way to track down issues with Focus is... debugging .Net source code. No kidding. It saved me a lot of time many times. To enable .net source code debugging refer to Shawn Bruke's blog.

  3. Finally, general approach that I use to set focus from ViewModel is Attached Properties. I wrote very simple attached property, which can be set on any UIElement. And it can be bound to ViewModel's property "IsFocused" for example. Here it is:

     public static class FocusExtension
    {
    public static bool GetIsFocused(DependencyObject obj)
    {
    return (bool) obj.GetValue(IsFocusedProperty);
    }

    public static void SetIsFocused(DependencyObject obj, bool value)
    {
    obj.SetValue(IsFocusedProperty, value);
    }

    public static readonly DependencyProperty IsFocusedProperty =
    DependencyProperty.RegisterAttached(
    "IsFocused", typeof (bool), typeof (FocusExtension),
    new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));

    private static void OnIsFocusedPropertyChanged(
    DependencyObject d,
    DependencyPropertyChangedEventArgs e)
    {
    var uie = (UIElement) d;
    if ((bool) e.NewValue)
    {
    uie.Focus(); // Don't care about false values.
    }
    }
    }

    Now in your View (in XAML) you can bind this property to your ViewModel:

     <TextBox local:FocusExtension.IsFocused="{Binding IsUserNameFocused}" />

If this answer doesn't help, refer to the answer #2.

Set focus on textbox in WPF

In XAML:

<StackPanel FocusManager.FocusedElement="{Binding ElementName=Box}">
<TextBox Name="Box" />
</StackPanel>

How to lose focus on button press?

Re: Is there any way in xaml (e.g. in the view) to make the button get the keyboard focus when it is clicked by mouse? > A button does receive keyboard focus when it is clicked – provided the IsEnabled, Focusable, and IsHitTestVisible properties are all set to true as they are by default. To set keyboard focus programmatically call Keybaord.Focus as shown in the example below.

Contrary to a popular meme, Commands do not HAVE to be processed in the VM. If, on command execution, the view needs to be changed independently of the VM, the command can be handled in the view. In fact this is the native pattern for WPF.

The following example shows using the Command property on a button to process a command in the view. For simplicity the example does not have a VM. Even though the command is processed in the view, if there were a VM, the code behind in the view could make calls into it.

public partial class MainWindow : Window
{
public static readonly RoutedUICommand MyCommand = new RoutedUICommand("My Command", "MyCommand", typeof(MainWindow));
public String MyString { get; set; }

public MainWindow()
{
MyString = "some text";
DataContext = this; // this simple example has no VM
InitializeComponent();
}
private void MyCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
Button1.Content = MyString;
Keyboard.Focus(Button1);
}
}
<Window x:Class="fwLoseFocus.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:me="clr-namespace:fwLoseFocus">
<Window.CommandBindings>
<CommandBinding Command="me:MainWindow.MyCommand" Executed="MyCommand_Executed"/>
</Window.CommandBindings>
<StackPanel>
<TextBox Text="{Binding MyString}"/>
<Button x:Name="Button1" Command="me:MainWindow.MyCommand"/>
</StackPanel>
</Window>

WPF MVVM: Set focus to current selected item in Datagrid on button click

The following should work:

if (myDataGrid.SelectedIndex > -1) {
var container = (DataGridRow) myDataGrid.ItemContainerGenerator.ContainerFromIndex(myDataGrid.SelectedIndex);
if (container != null) {
container.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}
}

You can put that code into Button.Click event (nothing wrong here, what we are doing is completely view-only thing) or if you don't like code-behind you can create attached property\behavior from that.

WPF lostfocus not firing when pressing a button

found a post of the exact opposite problem,
WPF Lost-Focus issue in same control.

surprisingly the opposite of that fix worked perfectly for me
add this property to the button:

Focusable="False"

the lostFocus event is triggered before the button clicked event. everything works as expected.



Related Topics



Leave a reply



Submit