Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set focus to textbox using MVVM?

Tags:

c#

mvvm

wpf

xaml

How to focus a textbox from ViewModel wpf?

<TextBox Name="PropertySearch"
         Text="{Binding UpdateSourceTrigger=PropertyChanged, 
                        Mode=TwoWay, Path=PropertySearch, 
                        ValidatesOnDataErrors=True}"  
         Width="110" 
         Height="25" 
         Margin="10" />
like image 909
Nivid Dholakia Avatar asked Jul 18 '11 18:07

Nivid Dholakia


People also ask

How do you focus a control in WPF?

An element can be turned into a focus scope in Extensible Application Markup Language (XAML) by setting the FocusManager attached property IsFocusScope to true . In code, an element can be turned into a focus scope by calling SetIsFocusScope.

What is Mvvm command?

Commands are an implementation of the ICommand interface that is part of the . NET Framework. This interface is used a lot in MVVM applications, but it is useful not only in XAML-based apps.


2 Answers

You can do this by adding a property to your ViewModel (or use an existing property) that indicates when the SetFocus should happen but the View should be responsible for actually setting the focus since that is purely View related.

You can do this with a DataTrigger.

View:

<Grid Name="LayoutRoot" DataContext="{StaticResource MyViewModelInstance}">
    <Grid.Style>
        <Style>
            <Style.Triggers>
                <DataTrigger Binding="{Binding UserShouldEditValueNow}" Value="True">
                    <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=PropertySearch}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Grid.Style>
    <TextBox   Name="PropertySearch"   Text="{Binding UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Path=PropertySearch, ValidatesOnDataErrors=True}" Width="110" Height="25" Margin="10" />
</Grid>

ViewModel:

// When you think the view should set focus on a control
this.UserShouldEditValueNow = true;

The example above is simplified by just using a boolean ViewModel property "UserShouldEditValueNow". You can add a property like this to your ViewModel or use some other exising property that indicates this state.

Note: So why is it done this way in MVVM? One reason is, suppose the View author decided to replace the TextBox with a ComboBox, or even better, suppose your property was an integer value that had both a TextBox to view/edit the number and a Slider as another way to edit the same value, both controls bound to the same property... how would the ViewModel know which control to set focus on? (when it shouldn't even know what control, or controls, are bound to it in the first place) This way the View can select which control to focus by changing the ElementName binding target in the DataTrigger Setter.

Happy coding!

like image 183
Harlow Burgess Avatar answered Oct 03 '22 13:10

Harlow Burgess


The question you should be asking yourself is "why does my ViewModel need to know which control has the focus?"

I'd argue for focus being a view-only property; it's an interaction property, and has nothing to do with the conceptual state. This is akin to the background color of a control: why would you represent it in the VM? If you need to manage the focus in a custom way, it's probably better to use a view-level object to do the job.

like image 26
Ben Straub Avatar answered Oct 03 '22 13:10

Ben Straub