I'm creating a wpf project using MVVM and Bxf as outlined in Rocky's videos.
It took me awhile to realize that my factory methods require an EventHandler parameter. I've tried converting the sample C# code, but I am unsuccessful. Looking in the Expert VB book, Chapter 15 on page 440 seems to address the async factory methods, but I'm having a hard time implementing them in my BO.
My GetGroupList method has an error on the addhandler line becuase callback does not exist in my BO. Here's my current Factory Methods and Data Access:
#Region "Factory Methods" #End Region #Region "Data Access" RaiseListChangedEvents = True #End Region
Return DataPortal.FetchChild(Of Groups)()
End Function
Public Shared Sub GetGroupList(ByVal callback As EventHandler(Of DataPortalResult(Of Groups)))
Dim dp = New DataPortal(Of Groups)()
AddHandler dp.FetchCompleted, AddressOf callback
dp.BeginFetch()
End Sub
RaiseListChangedEvents = False
Dim reader As New Dal.Reader
Dim groups As List(Of Dal.DtoGroup) = reader.GetGroups
For Each grp In groups
Dim dtoGroup As New Dal.DtoGroupdto
Group.Name = grp.Namedto
Group.Path = grp.Path
Me.Add(Group.GetGroup(dtoGroup))
Next
If you can upgrade to VB 10 and Visual Studio 10 your life will be much easier, because VB now has multi-line lambda support. That allows you to use comparable syntax to C#.
If you are still using VB 9, you are about to discover why I quit maintaining CSLA in VB - without multi-line lambda support it is much harder to do async programming.
Basically, in VB9 you often have to create an intermediate object to maintain state between the point where you start the async call and the point where the async call completes. In the simplest cases you don't need to do this, and you can just provide the AddressOf the callback handler, but if there's any information around the point of the async call that is needed in the async handler, you need this intermediate state object.
Before I spend a lot of time either way - are you VB 9 or 10?
VB 10 with VS 2010
I've continued to work on it and the following code fetches the data and appears to populate the List, but nothing appears in grid. The viewmodel is not firing OnRefreshed because I assume callback is not properly implemented in my code:
#Region "Factory Methods"
Public Shared Function GetGroups() As Groups
Return DataPortal.FetchChild(Of Groups)()
End Function
Public Shared Sub GetGroupList(ByVal callback As EventHandler(Of DataPortalResult(Of Groups)))
Dim dp = New DataPortal(Of Groups)()
dp.BeginFetch(callback)
End Sub
#End Region
#Region "Data Access"
Private Overloads Sub DataPortal_Fetch()
RaiseListChangedEvents = False
Dim reader As New Dal.Reader
Dim groups As List(Of Dal.DtoGroup) = reader.GetGroups
For Each grp In groups
Dim dtoGroup As New Dal.DtoGroup
dtoGroup.Name = grp.Name
dtoGroup.Path = grp.Path
Me.Add(Group.GetGroup(dtoGroup))
Next
RaiseListChangedEvents = True
End Sub
#End Region
End Class
I added my AddHandler back in to my second post on my GetGroupList method with the addtion of Invoke:
AddHandler dp.FetchCompleted, AddressOf callback.Invoke
This seems to be working now. However, my lack of comprehending this process makes me wonder if that's the correct solution and/or if I missed something else in my methods? I'll eventually "get it", but until then I want to make sure I'm not missing something else.
Thanks.
It is true that if you rely on things like ViewModel<T> or CslaDataProvider you shouldn't have to worry about the low-level details. Those components are designed to handle the async stuff so you don't have to.
The only exception is the factory method, where you need to set the callback parameter as being the handler for the completed event and you are set.
In fact, you can just use the static helper method on DataPortal to consolidate that all into one line of code, which simplifies the factory method even more:
DataPortal.BeginFetch(Of Groups)(callback)
Copyright (c) Marimer LLC