How to ensure all properties have loaded in Silverlight ViewModel pattern (Concurrency Control?)

早过忘川 提交于 2020-02-02 15:59:47

问题


I am struggling with a seemingly small but quite a painful predicament. I have a an object which acts as a view model to a control.

The underlying View Model is designed to help display a list of Group objects and their related Event (s) OUT OF ALL AVAILABLE EVENTS. In the underlying data model I have the following entities (EF) and their corresponding relationships:

Group -> GroupEvent <- Event

The view model has two observable collections - one for events and one for groups. The events collection represents all events available for any group. All events are loaded only once from the WCF RIA service and upon arrival each Event's entity data is copied into a local object which is pushed into the events collection.

In addition to the properties of the Event entity, the LocalEvent object also defines a "IsSelected" boolean property which by default is initialized to "false". This property is used in a CheckBoxGridColumn with two-way binding so that I can set the check box' state to checked or unchecked.

The Groups collection in the ViewModel is initialized the same way. I created a LocalGroup object which has a collection of LocalGroupEvents. In the constructor once the events have loaded, I load all Group entities (and their related GroupEvents) from the WCF RIA service. I copy all properties of each Group entity into a LocalGroup object, set its collection of LocalGroupEvents and finally push the LocalGroup into the Groups observable collection of the ModelView.

Finally the two collections are bound to their respective grids. The groups grid only displays the group name, while the Events grid displays a check box next to each event. The groups grid has a SelectedItemChanged event handler and whenever it occurs, I grab the LocalGroup object, I read all of it's LocalGroupEvents and set the "IsSelected" property in the Events grid to true for every event whose Id matches the Eventid in the LocalGroupEvents.

Well, this workflow works fine. 100% of the time. The issue I have is what if the data for the events arrives after the data for the groups? I mean, since any RIA service call is asynchronous, the threads are not paused to ensure that the data will arrive in the right order.

What if there is only one group, and it loads super fast before the events have had a chance to load? In that scenario even if the user clicks on the group, they will see nothing and will not be able to edit the selected group.

How do you ensure that data has arrived in the correct order before the UI binds to model-view?

Thanks,

Bleepzter


回答1:


You could use IResult and Coroutines from Caliburn Micro. It would allow you to populate those async things in a specific order.

IResult example, docs are here.

 public IEnumerable<IResult> GoForward()
    {
        yield return Loader.Show("Downloading...");
        yield return new LoadCatalog("Caliburn.Micro.Coroutines.External.xap");
        yield return Loader.Hide();
        yield return new ShowScreen("ExternalScreen");
    }

You can grab LoadData.cs from here. It's in Samples/GameLibrary/GameLibrary/Framework/Results. It's a Result someone wrote that adds an extension method to DataContext.



来源:https://stackoverflow.com/questions/6105228/how-to-ensure-all-properties-have-loaded-in-silverlight-viewmodel-pattern-concu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!