How to get the Detail Item async

Dec 29, 2011 at 8:18 PM

Hello,

I've got a hierarchical GridView that on the explose of the + button it calls the viewmodel to retrieve data passing the master item as parameter... for now I've been able doing so calling a method that looks like

 

public BindableCollection<myObject> GetDetailFromMasterItem(myMasterObject o)

{

var query = "....";

 

var op = query. Execute();

return new Bindable<....>(op.result...)

}

 

How can I have it async yielding the return? I'm new so please excuse if  I post this stupid question

Thanks

Dec 30, 2011 at 2:35 AM

Since I can't see your view and viewmodel, I assume the GridView just binds to the returned collection. BindableCollection<T> extends ObservableCollection<T>, which means it implements the CollectionChanged event, the close relative to PropertyChanged. Whenever you add to or remove from the collection, the CollectionChanged event fires and the XAML binding will automatically refresh.

So with that in mind, the above method should be in a repository following my suggested signature with the OnSuccess and OnFail callbacks.

Then in the view model, you simply create an empty BindableCollection<T> and do whatever you do now to bind the GridView to it. Then you make the call to the async repository method and in the OnSuccess callback you add the results to the empty collection using the AddRange method. Don't add item by item with the Add method as that will fire the CollectionChanged event every time and perform poorly. The AddRange method fires the CollectionChanged event at the end. Your GridView will automatically refresh, because it's listening to the CollectionChanged event.

Dec 30, 2011 at 8:14 AM

Hello MarcelGood,

now I've the code under my eyes...

I've got a behaviour attached to the Grid:

Here's the code

void AssociatedObject_LayoutUpdated(object sender, EventArgs e)

    {

        this.AssociatedObject.LayoutUpdated -= new EventHandler(AssociatedObject_LayoutUpdated);

 

        ComplexObject childGridcontext = this.AssociatedObject.DataContext as ComplexObject;

 

        if (childGridcontext != null)

        {

            ClearingHouseProductViewModel context = this.AssociatedObject.ParentOfType<UserControl>().DataContext as ClearingHouseProductViewModel;

 

            var items = context.GetDetailBySpecificParentValue(childGridcontext);

 

            this.AssociatedObject.ItemsSource = items;

        }

    }

and here's the method on my VM :

public override BindableCollection<ComplexObject> GetDetailBySpecificParentValue(ComplexObject item)

  {

      IsBusy = true;

 

      if (item == null) return null;

 

      BindableCollection<ComplexObject> res = new BindableCollection<ComplexObject>();

 

      if (item is CCGProdottiResult)

      {

          var castedObject = item as CCGProdottiResult;

 

          var t = _CHrepository.LoadDataSync(84, Date, castedObject.SYMBOL, castedObject.CLASS_TYPE);

 

          res = new BindableCollection<ComplexObject>(t);

 

      }

 

      IsBusy = false;

      return res;

 

  }

 

and here my repository

 

public System.Collections.Generic.IEnumerable<ComplexObject> LoadDataSync(int idFactory, DateTime date, string symbol, string classType)

  {

      var query = Manager.mySP(idFactory, date, symbol, classType);

 

      var op = query.Execute();

 

      return op.Cast<myType>();

  }

How can I call it async?

Thanks

 

Dec 30, 2011 at 11:28 AM

public INotifyCompleted LoadDataAsync(int idFactory, DateTime date, string symbol, string classType, Action<IEnumerable<ComplexObject>> onSuccess, Action<Exception> onFail)

{

var query = Manager.mySP(idFactory, date, symbol, classType);

 

var op = query.ExecuteAsync();

 

return op.OnComplete(onSuccess, onFail);

}

 

public override void GetDetailBySpecificParentValue(ComplexObject item, Action<BindableCollection<ComplexObject>> callback)

var castedObject = item as CCGProdottiResult;

  

if (castedObject != null)

{

IsBusy = true;

 

_CHrepository.LoadDataAsync(84, Date, castedObject.SYMBOL, castedObject.CLASS_TYPE,

result => { callback(new BindableCollection(result)); IsBusy = false; },

e => { IsBusy = false; <display error message>; });

}

}

 

void AssociatedObject_LayoutUpdated(object sender, EventArgs e)

{

this.AssociatedObject.LayoutUpdated -= new EventHandler(AssociatedObject_LayoutUpdated);

 

ComplexObject childGridcontext = this.AssociatedObject.DataContext as ComplexObject;

 

if (childGridcontext != null)

{

ClearingHouseProductViewModel context = this.AssociatedObject.ParentOfType<UserControl>().DataContext as ClearingHouseProductViewModel;

 

context.GetDetailBySpecificParentValue(childGridcontext, items => this.AssociatedObject.ItemsSource = items);

}

}

Dec 30, 2011 at 3:26 PM

Thanks Marcelgood, seems to be ok!

Thanks again!