Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting focus in WPF with MVVM

I have Grid with multiple Textboxes. Depending on actions the user might take focus should be changed to one of the textboxes. My current solution uses a string property in the ViewModel and a data trigger in xaml to change focus. It works nicely but it seems a rather roundabout way to achieve this so I was wondering if it could be done in a clearner way?

    <Grid.Style>
        <Style TargetType="Grid">
            <Style.Triggers>
                <DataTrigger Binding="{Binding FocusedItem}" Value="number">
                    <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=number}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding FocusedItem}" Value="name">
                    <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=name}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding FocusedItem}" Value="id">
                    <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=id}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Grid.Style>

As you can see the value of the property and the name of the element is the same so I would like to do this i a single trigger instead of having one trigger per element.

Maybe someone can come up with a cleaner way?

Thanks in advance

like image 843
Farawin Avatar asked Mar 12 '13 14:03

Farawin


1 Answers

The way I handled setting focus in one of my projects was by using a focus extension (I apologize I do not remember where I saw the original post this is from).

    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();
            }
        }
    }

And then in xaml file I use it as a Dependency Property:

<TextBox Uid="TB1" FontSize="13" localExtensions:FocusExtension.IsFocused="{Binding Path=TB1Focus}" Height="24" HorizontalAlignment="Left" Margin="113,56,0,0" Name="TB_UserName" VerticalAlignment="Top" Width="165" Text="{Binding Path=TB1Value, UpdateSourceTrigger=PropertyChanged}" />

You can then use a binding to set the focus.

like image 187
Heinrich Avatar answered Nov 19 '22 08:11

Heinrich