如何确保所有属性都已以 Silverlight ViewModel 模式加载(并发控制?)

发布于 2024-11-09 14:51:49 字数 1204 浏览 4 评论 0原文

我正在与一个看似很小但相当痛苦的困境作斗争。我有一个对象充当控件的视图模型。

底层视图模型旨在帮助显示所有可用事件中的组对象及其相关事件的列表。在底层数据模型中,我有以下实体(EF)及其相应的关系:

Group -> GroupEvent <- Event

视图模型有两个可观察的集合 - 一个用于事件,一个用于组。事件集合代表任何组可用的所有事件。所有事件仅从 WCF RIA 服务加载一次,到达后,每个事件的实体数据都会复制到本地对象中,该对象会被推送到事件集合中。

除了 Event 实体的属性之外,LocalEvent 对象还定义了一个“IsSelected”布尔属性,默认情况下初始化为“false”。此属性在具有双向绑定的 CheckBoxGridColumn 中使用,以便我可以将复选框的状态设置为选中或未选中。

ViewModel 中的 Groups 集合以相同的方式初始化。我创建了一个 LocalGroup 对象,其中包含 LocalGroupEvents 的集合。在构造函数中,加载事件后,我会从 WCF RIA 服务加载所有 Group 实体(及其相关的 GroupEvent)。我将每个 Group 实体的所有属性复制到 LocalGroup 对象中,设置其 LocalGroupEvents 集合,最后将 LocalGroup 推送到 ModelView 的 Groups 可观察集合中。

最后,这两个集合绑定到它们各自的网格。 组网格仅显示组名称,而事件网格则在每个事件旁边显示一个复选框。组网格有一个 SelectedItemChanged 事件处理程序,每当它发生时,我都会获取 LocalGroup 对象,读取它的所有 LocalGroupEvents 并将事件网格中的“IsSelected”属性设置为 true,对于每个 Id 与 LocalGroupEvents 中的 Eventid 匹配的事件。

嗯,这个工作流程运行得很好。 100% 的时间。我遇到的问题是,如果事件的数据在组的数据之后到达怎么办?我的意思是,由于任何 RIA 服务调用都是异步的,因此线程不会暂停以确保数据按正确的顺序到达。

如果只有一组,并且在事件有机会加载之前加载速度非常快怎么办?在这种情况下,即使用户单击该组,他们也不会看到任何内容,并且无法编辑所选组。

在 UI 绑定到模型视图之前,如何确保数据以正确的顺序到达?

谢谢,

Bleepzter

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心清如水 2024-11-16 14:51:50

您可以使用 Caliburn Micro 的 IResult 和协程。它允许您按特定顺序填充这些异步事物。

IResult 示例,文档位于此处

 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");
    }

您可以从此处获取LoadData.cs。它位于 Samples/GameLibrary/GameLibrary/Framework/Results 中。这是某人编写的 Result,它向 DataContext 添加了扩展方法。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文