简体   繁体   English

如何将WPF UserControl挂钩到绑定的ViewModel对象的事件?

[英]How can I hook a WPF UserControl to an event of a bound ViewModel object?

Say I have a UserControl with a DependencyProperty to bind to an ObservableCollection<Foo> object. 假设我有一个带有DependencyPropertyUserControl绑定到ObservableCollection<Foo>对象。 The collection of Foo objects is actually sent to some Flash ActiveX object. Foo对象的集合实际上被发送到某个Flash ActiveX对象。 Because of this, I can't "WPF bind" to properties of Foo objects. 因此,我无法“ WPF绑定”到Foo对象的属性。

When properties of a Foo object are updated by something else than the UserControl, I want the UserControl to be notified so it refreshes (ie resends all the Foo objects to the Flash object). 当Foo对象的属性被UserControl以外的其他对象更新时,我希望通知UserControl以便刷新(即,将所有Foo对象重新发送到Flash对象)。

I'm not quite sure how to handle this. 我不太确定该如何处理。 I can think of two not so distinct possibilities: 我可以想到两种不太明显的可能性:

  1. The UserControl subscribes to some event of the object that contains the ObservableCollection<Foo> object. UserControl订阅包含ObservableCollection<Foo>对象的对象的某些事件。 Whenever a property of a Foo object is changed, the event would fire, and so the UserControl would know to resend the Foo objects the Flash object. 每当Foo对象的属性发生更改时,就会触发该事件,因此UserControl会知道将Flash对象重新发送给Foo对象。

  2. Having the UserControl subscribed to the CollectionChanged event of the ObservableCOllection object, somehow cause the ObservableCOllection<Foo> object to raise the event with the Action NotifyCollectionChangedAction.Reset . 让UserControl订阅ObservableCOllection对象的CollectionChanged事件,以某种方式使ObservableCOllection<Foo>对象通过Action NotifyCollectionChangedAction.Reset引发事件。

     void OnFooCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (!_flashIsLoaded) return; if (e.Action == NotifyCollectionChangedAction.Reset) { ClearAndSendFoos(this, Foos); return; } .... 

Any idea how I can get any of the two above done, or how else I can get the UserControl to know it's time to refresh the collection? 知道如何完成以上两个操作中的任何一个,或者如何使UserControl知道是时候刷新集合了吗?

Something seems amiss here. 这里似乎有些不对劲。 You tagged the post with MVVM, so I suppose you are using it. 您用MVVM标记了该帖子,所以我想您正在使用它。

See, with Model, View, ViewModel, you should be doing this work between the ViewModel and the Model. 看到,有了Model,View,ViewModel,您应该在ViewModel和Model之间进行这项工作。 So the ViewModel would subscribe to the model's event and update. 因此,ViewModel将订阅模型的事件并进行更新。 If the Model doesn't have such an event, then inherit it and add it. 如果模型没有此类事件,则继承并添加它。 Then because the ViewModel implements INotifyPropertyChanged and because it uses an ObservableCollection, the View will already update. 然后,因为ViewModel实现了INotifyPropertyChanged,并且因为它使用了ObservableCollection,所以视图将已经更新。

Get the ViewModel's ObservableCollection to change and you don't have to have the UserControl subscribe to any event. 获取ViewModel的ObservableCollection进行更改,而不必让UserControl订阅任何事件。

The view should just display the ViewModel updates. 该视图应仅显示ViewModel更新。

You should consider having multiple ViewModels. 您应该考虑拥有多个ViewModel。

If you are interested in changes that happen in an item that you have in your ViewModel, create an ViewModel for those Items and change the ViewModel collection to a ObservableCollection<ItemViewModel> . 如果您对ViewModel中的某个项目发生的更改感兴趣,请为这些Items创建一个ViewModel,然后将ViewModel集合更改为ObservableCollection<ItemViewModel>

That way, you can bind to the properties you are actually interested in. 这样,您可以绑定到您实际感兴趣的属性。

Let's have an example: 让我们举个例子:

// the overall viewModel:
public class OverallViewModel : ViewModelBase
{
    public ObservableCollection<ProductViewModel> Products { get; set; };
}

// the item viewmodel:
public class ProductViewModel : ViewModelBase
{
    public string ProductName { get; set; }
    public int CountOfSold { get; set; }
}

So, you sell 5 Bananas. 因此,您卖出5个香蕉。 The count of Banana's sold changes. 香蕉的已售数量发生变化。 Since you bind directly to the item, there is no longer any need to have an extra event, the view (in your case the usercontrol) can update without any need to listen to an artificial collection event. 由于您直接绑定到项目,因此不再需要额外的事件,因此视图(在您的情况下为usercontrol)可以更新,而无需侦听人工收集事件。

I do not know much about Flash, but perhaps having a converter in your usercontrol that hosts the flash can help. 我对Flash知之甚少,但也许在用户控件中拥有一个托管Flash的转换器会有所帮助。 At least you do not have to crawl all the list, but just a single item. 至少您不必搜寻所有列表,而只需搜寻一个项目。

Hope this helps you 希望这对您有帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM