I'm attempting to improve my MVVM abilities in my next WP7 App (which is written in Vb.NET). I have a textbox that has been given focus and has a WP7 keyboard displayed. I am using command binding and a xyzzer's bindable Application bar (which is excellent).
http://bindableapplicationb.codeplex.com/
I want to be able to cancel the focus of the TextBox from the ViewModel, by setting focus on the form. Normally (Non MVVM) I would do this from within the form by calling:
Me.Focus()
But I can't do this from the ViewModel (and I shouldn't). At the moment I am raising an event out of the ViewModel and catching it on the form but its nasty. Is there a MVVM Friendly way of doing it? I haven't been using a Toolkit so far as there are limited examples in vb.net.
I have been using command binding.
Using Pedros example, and the other services I have previously implemented in my App I put together the following solution in vb.net:
Create an IFocus Interface, This Interface can be implemented by the focus service or a Mock
Public Interface IFocusInterface
Sub Focus()
End Interface
Create a IFocusable Interface. This will be implemented by the ViewModel and accepts an object that implements IFocusInterface.
Public Interface IFocusable
Property FocusService As IFocusInterface
End Interface
Implement the Focus Interface with a singleton pattern
Imports Microsoft.Phone.Controls
Public NotInheritable Class FocusService
Implements IFocusInterface
Private Sub New()
End Sub
Private Shared ReadOnly m_instance As New FocusService
Public Shared ReadOnly Property Instance() As FocusService
Get
Return m_instance
End Get
End Property
Public Sub Focus() Implements IFocusInterface.Focus
Dim rootFrame = TryCast(Application.Current.RootVisual, PhoneApplicationFrame)
If Not rootFrame Is Nothing Then
Dim page = TryCast(rootFrame.Content, PhoneApplicationPage)
If Not page Is Nothing Then
page.Focus()
Else
Throw New Exception("Unable to Cast the Root Frame Content into an Application Page")
End If
Else
Throw New Exception("Unable to Cast the RootVisual into a PhoneApplicationFrame")
End If
End Sub
End Class
In your ViewModel Implement IFocusable, and make sure you pass in the Focus Service Singleton into the ViewModel after the ViewModel is Constructed.
Public Class MyViewModel
Implements INotifyPropertyChanged
Implements IFocusable
' Property for the Focus Service
<Xml.Serialization.XmlIgnore()> Public Property FocusService As IFocusInterface Implements IFocusable.FocusService
Public Sub Focus()
If Not FocusService Is Nothing Then
FocusService.Focus()
Else
Throw New Exception("ViewModel hasn't been passed a Focus Service")
End If
End Sub
End Class
Dim tMyViewModel as New MyViewModel
tMyViewModel.FocusService = Vacation_Calc_Model.FocusService.Instance