C# MVVM共享属性

C# MVVM共享属性,c#,wpf,mvvm,static,static-members,C#,Wpf,Mvvm,Static,Static Members,有一些类似的问题,但它们不是一样的,所以我现在发布这个。我是MVVM的新手,所以我试图弄清楚如何创建一个类来保存可在视图之间共享的属性。因此,如果我在一个视图中设置了一个属性,那么所有其他视图都会收到其更改的通知,并相应地调整其属性 我现在拥有的东西相当粗糙,绝对不是我想要使用的东西。这是我的通用类,它将保存所有属性: public static class Common { private static string _title; public static string T

有一些类似的问题,但它们不是一样的,所以我现在发布这个。我是MVVM的新手,所以我试图弄清楚如何创建一个类来保存可在视图之间共享的属性。因此,如果我在一个视图中设置了一个属性,那么所有其他视图都会收到其更改的通知,并相应地调整其属性

我现在拥有的东西相当粗糙,绝对不是我想要使用的东西。这是我的通用类,它将保存所有属性:

public static class Common
{
    private static string _title;
    public static string Title
    {
        get { return _title; }
        set
        {
            if (_title == value)
            {
                return;
            }

            _title = value;
            OnPropertyChanged("Title");
        }
    }

    public static void Load()
    {
        // set properties here
    }

    public static event PropertyChangedEventHandler PropertyChanged;

    private static void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(typeof(SettingsWorker), new PropertyChangedEventArgs(name));
        }
    }
}
…我必须从每个ViewModel订阅它:

Common.PropertyChanged += Common_PropertyChanged;

private void Common_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    Title = Common.Title;
}
    public AnotherViewModel
    {
        SendMessage(MessageTokens.SomeToken, new NotificationEventArgs(WhateverYouWantToSend));
    }
但这就是崩溃发生的地方。我可以从
属性changedeventargs
获取属性名,但我不知道如何获取值。因此,我不得不更新所有的属性,这会让维护变得很困难。代码变得一团糟


我基本上是在尝试获取ViewModels可以共享的属性。我如何才能做到这一点呢?

因此,如果您有其他视图希望在属性更改时得到通知,我将假定您对这些视图中的每个视图都有一个单独的viewmodel。在这种情况下,您需要的是“viewmodels如何与其他viewmodels对话?”为了获得良好的学习体验,我建议您研究观察者模式。如果您不喜欢这种风格,那么我建议您考虑使用MVVM框架,如“SimpleMVVM、Catel或许多其他框架”(只需要查找一些)。然后,一旦在项目中有了该框架,我将创建一个baseviewmodel类,所有viewmodels都将继承该类。完成后,您可以利用框架messenger系统。基本上它看起来像:

    public YourViewModel()
    {           
        RegisterToReceiveMessages(MessageTokens.SomeToken, OnChangeCallYourMethodToAddress); //The MessageTokens is something you generally create ur self.
    }

    #region Notifications
    void OnChangeCallYourMethodToAddress(object sender, NotificationEventArgs<SlideShowLocale> e)
    {
        SomeProperty = e.Data;
    }

因此,基本上,通过声明所需的令牌,它会找到使用该令牌注册的viewmodel,并侦听任何传入的消息。

看起来您只需要在多个位置显示一些全局数据。最直接的方法是将其设置为与普通ViewModel类类似的类,然后将其提供给其他每个ViewModel,并将其公开以直接绑定(而不是将属性复制到每个ViewModel中)。您可以使用IOC来实现这一点,也可以使其静态可用,这与您现在使用它的方式更为相似

如果您选择静态方向,则需要进行的关键更改是使用单例而不是静态类,以便允许属性更改通知工作。绑定可以在实例上使用INPC,但不能在静态类上使用。普通类看起来更像这样:

public class Common : INotifyPropertyChanged
{
    private static Common _instance = null;

    protected Common()
    {
    }

    public static Common GetInstance()
    {
        if (_instance == null)
            _instance = new Common();

        return _instance;
    }

    private string _title;
    public string Title
    {
        get { return _title; }
        set
        {
            if (_title == value)
                return;
            _title = value;
            OnPropertyChanged("Title");
        }
    }

    public void Load()
    {
    }

    public virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventArgs ea = new PropertyChangedEventArgs(propertyName);
        if (PropertyChanged != null)
            PropertyChanged(this, ea);
    }

    public event PropertyChangedEventHandler PropertyChanged;
}
有很多不同的方法可以使用它。这里有一个更直接的例子:

public class SomeViewModel : ViewModelBase
{
    public Common CommonData { get; private set; }

    public SomeViewModel()
    {
        CommonData = Common.GetInstance();
    }
}
然后,在XAML中,您可以绑定到公共类中的属性并获得更改通知,即使在不同的VM使用中也是如此

<TextBox Text="{Binding Path=CommonData.Title}"/>


还可以选择将单例作为属性进行访问,并使用x:Static直接从XAML绑定到它,但这与您所要求的方向略有不同。

这就是事件聚合器变得有用的地方。这是Prism的一部分,与MVVM非常兼容。回答得很好。正是我想要的。非常感谢。