【问题标题】:Binding to WPF ViewModel properties绑定到 WPF ViewModel 属性
【发布时间】:2011-02-01 03:27:21
【问题描述】:

我只是在玩 WPF 和 MVVM,并且我制作了一个简单的应用程序,它显示一个 Rectangle,它会在网络可用性发生变化时改变颜色。

但是当这种情况发生时,我得到这个错误:Cannot use a DependencyObject that belongs to a different thread than its parent Freezable.

代码

XAML

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="400" Width="600">
<DockPanel LastChildFill="True">
    <Rectangle x:Name="networkStatusRectangle" Width="200" Height="200" Fill="{Binding NetworkStatusColor}" />
</DockPanel>
</Window>

代码隐藏

使用 System.Windows; 使用 WpfApplication1.ViewModels;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            DataContext = new NetworkViewModel();
        }
    }
}

视图模型

using System.ComponentModel;
using System.Net.NetworkInformation;
using System.Windows.Media;

namespace WpfApplication1.ViewModels
{
    public class NetworkViewModel : INotifyPropertyChanged
    {
        private Brush _NetworkStatusColor;

        public Brush NetworkStatusColor
        {
            get { return _NetworkStatusColor; }
            set
            {
                _NetworkStatusColor = value;
                NotifyOfPropertyChange("NetworkStatusColor");
            }
        }

        public NetworkViewModel()
        {
            NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
        }

        protected void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
        {
            if (e.IsAvailable)
            {
                this.NetworkStatusColor = new SolidColorBrush(Colors.Green);
            }
            else
            {
                this.NetworkStatusColor = new SolidColorBrush(Colors.Red);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        public void NotifyOfPropertyChange(string propertyName)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

我假设我应该通过调用某些东西来更改 NetworkStatusColor 属性?

【问题讨论】:

    标签: wpf mvvm


    【解决方案1】:

    你猜对了。这是Dispatcher 类和.Invoke 方法你想看看。

    有点像这样:

    if (this.Dispatcher.Thread != Thread.CurrentThread)
    {
        this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(...your method...), any, params, here);
        return
    }
    

    MSDN article here 提供更多信息。

    【讨论】:

    • 酷。那么您是否应该始终让您的 ViewModel 派生自 DispatcherObject 类?
    • @MartinHN:不,抱歉。我不会让我的视图模型继承自 DispatcherObject。如果您从视图/窗口类中运行,则该代码是一个。如果您想从视图模型中执行此操作,您可以在绑定(或创建)视图模型时从视图中传递调度程序。或者,如果您的视图模型是在主线程上创建的,您可以使用 Dispatcher.CurrentDispatcher。看看这个问题以获得从视图模型访问窗口调度程序的其他一些建议:stackoverflow.com/questions/2354438/…
    • 虽然,如果你要在你的视图模型上使用 DependencyProperties,你最终还是会在层次结构中间接继承 DispatcherObject(它是 DependencyObject 的父类),所以我想这取决于什么你是怎么做的。
    • 好的,我想我会选择一个通用的助手,灵感来自 MVVM Light Toolkit:mvvmlight.codeplex.com/sourcecontrol/network/…
    【解决方案2】:

    使用 MVVM,您在处理调度时有几个选择。您可以向您的视图发送某种消息以使其为您调用操作,或者您可以创建某种可以轻松模拟的抽象调度程序服务。

    看看MVVM Light 工具包,因为它包含一个简单的调度程序服务,您可以使用/复制。

    【讨论】:

      猜你喜欢
      • 2015-11-24
      • 2016-01-11
      • 2011-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-25
      相关资源
      最近更新 更多