【发布时间】:2014-03-29 19:32:47
【问题描述】:
如何从单独的视图模型调用用户控件上的函数?
在我的场景中,我有一个带有 ScoreDisplay UserControl 的“主”视图:
<local:ScoreDisplay/>
此控件将显示我的游戏中 n 名玩家的得分。主视图模型连接到一个游戏控制器,该控制器为其提供分数更新。我需要将这些更新后的分数传递给 UserControl(并运行一些动画、重要的逻辑等)
我看到了几个选项:
创建一个“分数”依赖属性并将其绑定到视图模型的分数集合。我看到这种方法的唯一问题是,无论何时修改它,我都需要去看看有什么变化,这样我才能运行适当的动画。这样做当然是可能的,但似乎并不“正确”。
让 ViewModel 在 UserControl 上调用“UpdateScore”函数。当然,唯一的问题是 ViewModel 不应该知道任何关于 View 的信息,因此不应该有执行此操作所需的参考。
让 UserControl 注册视图模型上的“ScoreUpdated”事件。这似乎是最好的选择,但我不知道如何获取对 ViewModel 的引用以注册事件。
哪个选项(如果有)是正确的方法?如果是 (2) 或 (3),我该如何实现?
编辑:
需要明确的是,分数集合中的 值 正在发生变化(集合本身保持不变)。我可以在分数 int 周围放置一个包装器并收听 PropertyChanged,但同样,这似乎是一个简单问题的过于复杂的方法。如果这是最好的解决方案,请告诉我!
编辑 2:
UpdateScore 是一个函数,(理论上)接受更新分数的索引和添加到该玩家分数的值(它可以接受整个分数)。然后它会导致玩家的钉子沿着纸条轨道移动到新位置。
每当玩家获得积分时都会调用它(这是一个 Cribbage 游戏,所以这种情况经常发生)。视图模型附加到一个游戏控制器,该控制器引发一个事件以通知 VM 玩家已获得积分。视图模型基本上只需要将此信息传递给ScoreDisplay 用于显示/动画等。
【问题讨论】:
-
如果分数是一个集合,您可以使用
ObservableCollection,因为它实现了INotifyCollectionChanges,它可以准确地告诉您发生了什么更改。 -
那行不通,因为它只是改变的值(而不是插入/删除)。不过感谢您的评论,我将编辑我的问题以包含此信息。
-
如果里面的元素实现了
INotifyPropertyChanged,集合也会通知这些变化。 -
里面的元素只是一个int(见我的编辑)。显式侦听包装器的 PropertyChanged 事件可能有效,但我仍然想知道是否有更好的方法。
-
@AnatoliyNikolaev 我试图在编辑 2 中包含更多信息。如果我能提供更多信息,请告诉我!