I needed to be able to set the Focus of a control, using MVVM. This means of course, that we can’t interact directly with the View, but instead must rely on Binding.

I found a very helpful post by Khalid Rafique which allows exactly this;

http://codenicely.blogspot.co.uk/2012/01/how-to-set-textbox-focus-in-silverlight.html

By making use of attached Interactivity Behaviours, we can Bind an IsFocused Property, allowing the focus of the selected control to be set..Very handy indeed.

The VB.net code is shown below;

Behaviour Class:

Imports System.Windows.Interactivity

 

Namespace Behaviours

 

    Public Class clsFocusBehavior

        Inherits Behavior(Of Control)

 

#Region "Properties"

 

        ''' 

        ''' The IsFocused Property, which is a backing for the IsFocusedProperty Dependancy Property

        ''' 

        ''' 

        ''' 

        ''' 

        Public Property IsFocused() As Boolean

            Get

                Return CBool(GetValue(IsFocusedProperty))

            End Get

            Set(value As Boolean)

                SetValue(IsFocusedProperty, value)

            End Set

        End Property

 

        ''' 

        ''' The Has Initial Focus Property, which is a backing for the HasInitialFocusProperty Dependancy Property

        ''' 

        ''' 

        ''' 

        ''' 

        Public Property HasInitialFocus() As Boolean

            Get

                Return CBool(GetValue(HasInitialFocusProperty))

            End Get

            Set(value As Boolean)

                SetValue(HasInitialFocusProperty, value)

            End Set

        End Property

 

#End Region

 

#Region "Dependancy Properties"

 

        ''' 

        ''' Expose an IsFocused Dependancy Property to allow Binding

        ''' 

        ''' 

        Public Shared ReadOnly IsFocusedProperty As DependencyProperty = DependencyProperty.Register("IsFocused", GetType(Boolean), GetType(clsFocusBehavior), New PropertyMetadata(False, Sub(d, e)

                                                                                                                                                                                               If CBool(e.NewValue) Then

                                                                                                                                                                                                   DirectCast(d, clsFocusBehavior).AssociatedObject.Focus()

                                                                                                                                                                                               End If

                                                                                                                                                                                           End Sub))

 

        ''' 

        ''' Expose a HasInitialFocus Property, which allows Binaind dicating if the Control should be focuses Initially

        ''' 

        ''' 

        Public Shared ReadOnly HasInitialFocusProperty As DependencyProperty = DependencyProperty.Register("HasInitialFocus", GetType(Boolean), GetType(clsFocusBehavior), New PropertyMetadata(False, Nothing))

 

#End Region

 

#Region "Helper Subs"

 

        ''' 

        ''' Override the OnAttached Sub... Add Event Handlers

        ''' 

        ''' 

        Protected Overrides Sub OnAttached()

 

            AddHandler AssociatedObject.GotFocus, Function(sender, args) InlineAssignHelper(IsFocused, True)

            AddHandler AssociatedObject.LostFocus, Function(sender, a) InlineAssignHelper(IsFocused, False)

            AddHandler AssociatedObject.Loaded, Sub(o, a)

                                                    If HasInitialFocus OrElse IsFocused Then

                                                        AssociatedObject.Focus()

                                                    End If

                                                End Sub

            MyBase.OnAttached()

        End Sub

 

        ''' 

        ''' Used to simplify assigning the Target Vaues of Control Events

        ''' 

        ''' 

        ''' 

        ''' 

        ''' 

        ''' 

        Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T

            target = value

            Return value

        End Function

 

#End Region

 

    End Class

 

End Namespace

XAML to add to View Header Namepaces:

xmlns:Behaviors="clr-namespace:CriticalPath_WPF_MVVM_EF.Behaviours"

             

XAML to add to control:

<i:Interaction.Behaviors>

    <Behaviors:clsFocusBehavior HasInitialFocus="False" IsFocused="{Binding DataContext.OrderNumberFocus, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"/>

</i:Interaction.Behaviors>

Code to add to ViewModel:

Private _OrderNumberFocus As Boolean

 

''' 

''' The Order Number Focus

''' 

''' 

''' 

''' 

Public Property OrderNumberFocus As Boolean

    Get

        Return _OrderNumberFocus

    End Get

    Set(value As Boolean)

        _OrderNumberFocus = value

        OnPropertyChanged("OrderNumberFocus")

    End Set

End Property

Set the Focus using;

OrderNumberFocus = True

By |2017-07-24T08:33:18+01:00January 1st, 2013|.Net Framework, MVVM, Tips, VB.net, Visual Studio, WPF|0 Comments

About the Author:

Leave A Comment