【问题标题】:VisualState Binding threading issueVisualState 绑定线程问题
【发布时间】:2011-08-19 18:56:09
【问题描述】:

我在 Windows Phone 7 中有一个录音应用程序。 该应用程序允许用户播放录制的声音。

我尽量遵守 MVVM 指南。

我在所有录音的列表中有一个播放/停止按钮。每个录音都有自己的 ViewModel,除此之外,它还控制相应播放/停止按钮的外观。

按钮的样式中定义了自定义的视觉状态。

Visual State 使用以下方法绑定到 ViewModel 的属性,如下所示: http://tdanemar.wordpress.com/2009/11/15/using-the-visualstatemanager-with-the-model-view-viewmodel-pattern-in-wpf-or-silverlight/

实现了这种方法后,每当我想更改播放/停止按钮的外观时,我都需要将我的 ViewModel 中的公共字符串属性(名为“PlayStopVisualState”)设置为“PlayingState”或“Normal”,并且这将为我的按钮分配适当的视觉状态。

问题是当用户按下播放按钮时,会在后台线程中创建一个 SoundEffectInstance 来播放声音。然后线程等待播​​放结束。当录音播放结束时(我必须在同一个后台线程中跟踪它,或者创建另一个仅跟踪 SoundEffectInstance.State)我将 PlayStopVisualState 属性设置回“正常”,但我得到一个跨线程引用异常。 MVVM 不是专门为允许开发人员在视图模型中操作逻辑变量而设计的,而不必担心对它们的更改如何反映在视图中吗?

我知道我需要在 Dispatcher 线程中调整 PlayStopVisualState 属性以使问题消失,但这是不对的。在我看来,它违背了 MVVM 的全部目的,只留下了组织优势。

还是我做错了什么?谢谢。

更新: 我已经使用

解决了这个问题
Deployment.Current.Dispatcher

但在我看来,这是一个非常“丑陋”的解决方案,因为我几乎都遵循了 MVVM 模式。

【问题讨论】:

  • '每个记录都有自己的 ViewModel' 不应该是一个模型吗?
  • 逻辑上可以是任何一种方式。例如,电话页面很可能有一个视图模型和它依赖于 UI 的不同模型。但是当我们有一个控件的视图模型时,例如,每个列表项在逻辑上都可以有自己的视图模型。就我个人而言,我认为这没有什么误解。
  • 我不是说错了,这似乎有点奇怪,所以我想知道这是不是一个错字。

标签: silverlight windows-phone-7 mvvm multithreading


【解决方案1】:

使用 Dispatcher 来反映 UI 绑定值是正确的做法,是的。

您忘记的是您的 ViewModel 是在 UI 线程上创建的。因此,从后台线程对 ViewModel 的任何更改都将是跨线程操作。

您应该考虑是否真的需要后台线程。 ,或者如果您可以直接在 UI 线程上安排您的操作。

【讨论】:

  • Dispatcher.BeginInvoke 在 UI 线程上安排操作。这就是调度员的全部想法;-)
  • 好吧,问题是您必须拥有该 UI 调度程序的实例。就我而言,除了 Deployment.Current.Dispatcher 之外,我没有其他方法可以找到它。这是引用 UI 线程调度程序的正确方法吗?
  • 是的,这是从非 UI 上下文(例如 ViewModel)访问它的正确方法。
猜你喜欢
  • 1970-01-01
  • 2011-03-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-09
  • 2018-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多