wpf 在 MVVM (Caliburn micro) 中放置全局变量的位置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19428651/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:52:46  来源:igfitidea点击:

Where to place global variables in MVVM (Caliburn micro)

c#wpfmvvmcaliburn.micro

提问by Oscar Mateu

I'm refactoring a program done in WinForms to WPF and I'm using Caliburn.Micro as a framework to implement the MVVM pattern.

我正在将在 WinForms 中完成的程序重构为 WPF,并且我正在使用 Caliburn.Micro 作为框架来实现 MVVM 模式。

In the old program, I use a StatisHelperclass to allow different static variables like the theme, the language, the username or the rights of access, etc ..

在旧程序中,我使用一个StatisHelper类来允许不同的静态变量,如主题、语言、用户名或访问权限等。

I know that it could be insecure because these variables are public, but I doubt that my end users know how to access these values...

我知道这可能不安全,因为这些变量是公开的,但我怀疑我的最终用户是否知道如何访问这些值......

Anyway, I would like to know the best practice in MVVM to save global values (in concrete, I'm using Caliburn.Micro framework)that can be accessed for all the view-models.

无论如何,我想知道 MVVM 中保存全局值的最佳实践(具体来说,我正在使用 Caliburn.Micro 框架),所有视图模型都可以访问这些值。

Thank you for your responses.

谢谢你的回复。

采纳答案by Steve

You could use a singleton class (frowned upon by some). Note that the constructor is private, so nothing else can create an instance. Use the Instanceproperty to access it. The Instanceproperty in this example will only construct the singleton object the first time it's accessed.

您可以使用单例类(有些人不赞成)。请注意,构造函数是private,因此没有其他任何东西可以创建实例。使用该Instance属性访问它。Instance此示例中的属性将仅在第一次访问时构造单例对象。

To use it, simply do something like var foo = Globals.Instance.SomeProperty.

要使用它,只需执行类似var foo = Globals.Instance.SomeProperty.

Note that this has nothing to do with WPF or MVVM, and could have been used in WinForms as well.

请注意,这与 WPF 或 MVVM 无关,也可以在 WinForms 中使用。

public class Globals {
    private Globals _Instance;
    public Globals Instance {
        get {
            if (_Instance == null)
                _Instance = new Globals();
            return _Instance;
        }
    }

    private Globals() {
    }

    public string SomeProperty { get; set; }
}

回答by Sheridan

I use a custom StateManagerclass that implements the Singletonpattern so that there is only one of these instances in the application:

我使用一个StateManager实现该Singleton模式的自定义类,以便应用程序中只有这些实例之一:

public class StateManager : INotifyPropertyChanged
{
    private static StateManager instance = new StateManager();

    /// <summary>
    /// Initialises a new empty StateManager object.
    /// </summary>
    public StateManager() { }

    /// <summary>
    /// Gets the single available instance of the application StateManager object.
    /// </summary>
    public StateManager Instance
    {
        get { return instance; }
    }

    ...
}

This is then referenced in my base view model, so that all of my view models have access to it:

然后在我的基本视图模型中引用它,以便我的所有视图模型都可以访问它:

public StateManager StateManager
{
    get { return stateManager.Instance; }
}

Furthermore, because it is referenced in my view model classes, I can also Bindto the values in XAML:

此外,因为它在我的视图模型类中被引用,我还可以引用BindXAML 中的值:

<Window Title="{Binding StateManager.WindowTitle, Mode=OneWay}" ... />

回答by Ibrahim Najjar

Well my answer is a combination of ideas from the @Steve and @Sheridan and the link in the comment.

好吧,我的答案是来自@Steve 和@Sheridan 的想法以及评论中的链接的组合。

First of all, I have to say separate the data from the code.

首先,我不得不说将数据与代码分开。

As for the data, I would use those Resxfiles to store all those kinds of resources, whether they are binary resources like simple audio files, images, localizable strings, etc .., because this makes it easy to swap them at run-time.

至于数据,我会使用这些Resx文件来存储所有这些类型的资源,无论它们是二进制资源,如简单的音频文件、图像、可本地化的字符串等,因为这样可以很容易地在运行时交换它们.

As for the code, I would use a collection like IConfigurationProviderlike this:

至于代码,我会使用这样的集合IConfigurationProvider

public interface IConfigurationProvider {

    GetResourceByName<T>(string key); // T is the type of the requested resource

    // THIS IS A SIMPLIFIED VERSION, YOU CAN HAVE MORE METHODS
    // ACCORDING TO YOUR NEEDS 

}

The implementation of this interface could use the Resxfiles to store and retrieve resources, then you can inject those resources into the different classes that need it.

该接口的实现可以使用Resx文件来存储和检索资源,然后您可以将这些资源注入到需要它的不同类中。

This haves some advantages like:

这有一些优点,例如:

  • Better testability
  • Can use different media to store the resource data without changing the interface
  • Swap the implementation at run-time, you can use DI now.
  • More clear where is the data coming from
  • 更好的可测试性
  • 可以在不改变接口的情况下使用不同的媒体来存储资源数据
  • 在运行时交换实现,您现在可以使用 DI。
  • 更清楚数据来自哪里