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.InteractivityNamespace BehavioursPublic Class clsFocusBehavior
Inherits Behavior(Of Control)#Region "Properties"
''' <summary> ''' The IsFocused Property, which is a backing for the IsFocusedProperty Dependancy Property ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks>Public Property IsFocused() As Boolean
GetReturn CBool(GetValue(IsFocusedProperty))
End Get
Set(value As Boolean)
SetValue(IsFocusedProperty, value)
End Set
End Property
''' <summary> ''' The Has Initial Focus Property, which is a backing for the HasInitialFocusProperty Dependancy Property ''' </summary> ''' <value></value> ''' <returns></returns> ''' <remarks></remarks>Public Property HasInitialFocus() As Boolean
GetReturn CBool(GetValue(HasInitialFocusProperty))
End Get
Set(value As Boolean)
SetValue(HasInitialFocusProperty, value)
End Set
End Property
#End Region#Region "Dependancy Properties"
''' <summary> ''' Expose an IsFocused Dependancy Property to allow Binding ''' </summary> ''' <remarks></remarks>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))
''' <summary> ''' Expose a HasInitialFocus Property, which allows Binaind dicating if the Control should be focuses Initially ''' </summary> ''' <remarks></remarks>Public Shared ReadOnly HasInitialFocusProperty As DependencyProperty = DependencyProperty.Register("HasInitialFocus", GetType(Boolean), GetType(clsFocusBehavior), New PropertyMetadata(False, Nothing))
#End Region#Region "Helper Subs"
''' <summary> ''' Override the OnAttached Sub... Add Event Handlers ''' </summary> ''' <remarks></remarks>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
''' <summary> ''' Used to simplify assigning the Target Vaues of Control Events ''' </summary> ''' <typeparam name="T"></typeparam> ''' <param name="target"></param> ''' <param name="value"></param> ''' <returns></returns> ''' <remarks></remarks>Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T
target = value
Return valueEnd Function
#End RegionEnd Class
End NamespaceXAML 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
''' <summary>''' The Order Number Focus''' </summary>''' <value></value>''' <returns></returns>''' <remarks></remarks>Public Property OrderNumberFocus As Boolean
Get Return _OrderNumberFocusEnd Get
Set(value As Boolean)
_OrderNumberFocus = value
OnPropertyChanged("OrderNumberFocus")End Set
End PropertySet the Focus using;
OrderNumberFocus = True
No comments:
Post a Comment