MVVM共享属性

B.K*_*.K. 1 c# wpf static static-members mvvm

在SO上有一些类似的问题,但它们并不是一样的安静,所以我发布了这个问题.我是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));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

...我必须从每个ViewModel订阅它:

Common.PropertyChanged += Common_PropertyChanged;

private void Common_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    Title = Common.Title;
}
Run Code Online (Sandbox Code Playgroud)

但这是故障发生的地方.我可以从中获取属性名称PropertyChangedEventArgs,但我不知道如何获得该值.因此,我被迫更新所有属性,这可能会让人讨厌维护.代码变得一团糟.

我基本上试图获得ViewModels可以共享的属性.我怎么能做到这一点?

Joh*_*wen 6

看起来您只想在多个地方显示一些全局数据.最直接的方法来做到这一点,只是让喜欢和正常ViewModel类,然后将其提供给您的每一个其他的ViewModels,并从他们暴露在直接绑定到(而不是复制都归到他们每个人).您可以使用IOC执行此操作,或者使其静态可用,更类似于您现在拥有的方式.

如果你去静态方向,你需要做的关键改变是使用单例而不是静态类,以便允许属性更改通知工作.绑定在实例上使用INPC而不是静态类.Common类看起来更像是这样的:

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;
}
Run Code Online (Sandbox Code Playgroud)

有很多不同的方法可以使用它.这是更直接的一个:

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

    public SomeViewModel()
    {
        CommonData = Common.GetInstance();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在XAML中,您可以绑定到公共类的属性并获取更改通知,甚至可以跨越不同的VM使用.

<TextBox Text="{Binding Path=CommonData.Title}"/>
Run Code Online (Sandbox Code Playgroud)

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