cslalight, demo001 as vb

cslalight, demo001 as vb

Old forum URL: forums.lhotka.net/forums/t/7020.aspx


germie posted on Thursday, May 28, 2009

i am trying to rewrite demo001 in vb. within the data access region there is a lambda expression "svc.GetDataCompleted += (o, e) =>" . i have read that vb does not allow multi-lined lambda expressions. how do i make this work in vb?

var svc = new DataService.WebServiceSoapClient();
svc.GetDataCompleted += (o, e) =>
{
 if (e.Error == null)
 {
   using (BypassPropertyChecks)
   {
     Id = e.Result.Id;
     Name = e.Result.Name;
     City = e.Result.City;
   }
 }
 handler(this, e.Error);
};
svc.GetDataAsync(criteria.Value);
}

RockfordLhotka replied on Thursday, May 28, 2009

You start to see why I shifted away from VB over the past few months. Until VB 10 comes out, developing software for Silverlight is really painful. As is developing anything for async .NET models.

The solution is complex. You need to define a message class to emulate the work the C# compiler does for you with a concept called a 'closure'.

I don't have time to translate the code - it is 2-3 times longer than the C# code, because you need to define a message class, create an instance of that class and pass it as a 'userstate' parameter to the GetDataAsync() method, so it comes into your GetDataCompleted event handler.

Psuedocode is:

Public Class Message
  Public Property Handler As <whatever type handler is>
End Class

...

Dim svc = New DataService...
Dim msg = New Message
msg.Handler = handler
AddHandler svc.GetDataCompleted, MyEventHandler
svc.GetDataAsync(criteria.Value, msg)

...

Private Sub MyEventHandler(o As Object, e As SomeEventArgsType)
  Dim msg = DirectCast(e.UserState, Message)
  If e.Error Is Nothing Then
    Using BypassPropertyChecks
      Id = e.Result.Id
...
    End Using
  End If
  msg.Handler(Me, e.Error)
End Sub

That's all from memory, and obviously I made up a bunch of type names - you'll have to sort those out - but hopefully this makes some sense.

germie replied on Monday, June 01, 2009

thanx rocky for your help and quick responce! the only thing i had to do a little different was with in the "MyEventHandler" where msg.Handler(Me. eError) is declared i first had to

Dim hdl as <whatever type handler is> = msg.Handler

then

hdl(Me, e.Error)

my next hurdle will be getting the save and cancel buttons working correctly. the cancel button does nothing and the save button throws an Invalid operation - update not allowed. i will investigate further and try and narrow it down as best i can and keep you updated.

germie

germie replied on Thursday, June 04, 2009

thanx once again, ive been working more on the DataPortal_Fetch and got the code as concise as i could. this is what i came up with.

   <System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)> _
   Public Sub DataPortal_Fetch(ByVal criteria As SingleCriteria(Of TestObject, Integer), ByVal handler As  _
                               Csla.DataPortalClient.LocalProxy(Of TestObject).CompletedHandler)
      Try
         Dim svc = New DataService.WebServiceSoapClient
         Dim msg = New GetDataAsycMessage
         msg.Handler = handler
         AddHandler svc.GetDataCompleted, AddressOf GetDataHandler
         svc.GetDataAsync(criteria.Value, msg)
      Catch ex As Exception
         handler(Me, ex)
      End Try
   End Sub

   Private Sub GetDataHandler(ByVal o As Object, ByVal e As DataService.GetDataCompletedEventArgs)
      If e.Error Is Nothing Then
         Using BypassPropertyChecks
            Id = e.Result.Id
            Name = e.Result.Name
            City = e.Result.City
         End Using
      End If
      DirectCast(e.UserState, GetDataAsycMessage).Handler(Me, e.Error)
   End Sub

   Public Class GetDataAsycMessage
      Public Handler As Csla.DataPortalClient.LocalProxy(Of TestObject).CompletedHandler
   End Class

this code works fine. the problem i am having is with the save and cancel buttons. i belive its the same problem. it seems that when i click the save button it creates a new TestObject instead of referencing the original one. here is the code for the DataPortal_Update that i created.

   <System.ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)> _
   Public Overrides Sub DataPortal_Update(ByVal handler As Csla.DataPortalClient.LocalProxy(Of TestObject).CompletedHandler)
      Try
         Dim svc = New DataService.WebServiceSoapClient
         Dim msg = New GetDataAsycMessage
         msg.Handler = handler
         AddHandler svc.UpdateDataCompleted, AddressOf UpdateDataHandler
         Dim Data As New DataService.Data
         Using (BypassPropertyChecks)
            Data.Id = Me.Id
            Data.Name = Me.Name
            Data.City = Me.City
         End Using
         svc.UpdateDataAsync(Data, msg)
      Catch ex As Exception
         handler(Me, ex)
      End Try
   End Sub

   Private Sub UpdateDataHandler(ByVal o As Object, ByVal e As DataService.UpdateDataCompletedEventArgs)
      If e.Error Is Nothing Then
         Using (BypassPropertyChecks)
            Id = e.Result.Id
            Name = e.Result.Name
            City = e.Result.City
         End Using
         DirectCast(e.UserState, GetDataAsycMessage).Handler(Me, e.Error)
      End If
   End Sub

when i put a stop within the try catch block, me.id, etc. is empty. the xaml code i am using is identical to what is shown in your Demo001 code.  i even tried naming the TextBox in xaml to "txtName" etc. and hard codeing it in and it still doesnt work. intellisense does not know "txtName".the problem with the cancel button is nothing happens. im all out of ideas here.

germie

RockfordLhotka replied on Thursday, June 04, 2009

Is the code getting to your UpdateDataHandler() method? Or is it calling the handler in the Catch block of the DataPortal_Update() method?

germie replied on Thursday, June 04, 2009

wow, such a quick responce. u beat me to it.  i solved it just now and came to post what my problem was. i was declaring my properties wrong. i wrote them up trying to use a private variable like this as described in "Expert VB 2008 Business Objects"

   Private Shared IdProperty As PropertyInfo(Of Integer) = RegisterProperty(New PropertyInfo(Of Integer)("Id"))
   Private mId As Integer = IdProperty.DefaultValue
   Public Property Id() As Integer
      Get
         Return GetProperty(IdProperty, mId)
      End Get
      Private Set(ByVal value As Integer)
         SetProperty(IdProperty, mId, value)
      End Set
   End Property

when i changed it to this, not using the private, both the save and the cancel buttons worked!

   Private Shared IdProperty As PropertyInfo(Of Integer) = RegisterProperty(New PropertyInfo(Of Integer)("Id"))
   Public Property Id() As Integer
      Get
         Return GetProperty(IdProperty)
      End Get
      Private Set(ByVal value As Integer)
         SetProperty(IdProperty, value)
      End Set
   End Property

dont know why, maybe u have an idea. thanx

germie

Copyright (c) Marimer LLC