代码之家  ›  专栏  ›  技术社区  ›  bitbonk

全局设置视图模型

  •  3
  • bitbonk  · 技术社区  · 15 年前

    我有一些全局设置,它们应该来自于ViewModel,并且应该对所有用户控件中的所有数据模板都可用。它包括GlobalAlbutomMargin、GlobalStrokeWidth或GlobalWorkspaceBackgroundColor等内容。这些东西在视图模型中,因为用户可以在运行时编辑这些设置。

    您将如何以一种良好的MVVM方式来实现这一点?

    我想买一个单件的GlobalsettingsViewModel。这是首选方法吗?如果是,如何从XAML访问单例实例?

    另一种方法是将globalSettings传递给我的应用程序中存在的所有ViewModel实例,这样我就可以从我为其创建数据模板的ViewModels中进行访问。但感觉不干净。

    第三种方法是放弃ViewModel方法,将其定义为XAML资源,并在运行时使用FindResource动态设置资源。

    你能描述一下,你将如何设计你的应用程序来支持这个场景吗?

    2 回复  |  直到 15 年前
        1
  •  3
  •   Drew Marsh    15 年前

    我将创建一个类型来将您的视图模型表示为一个类,然后在应用程序级别将它的实例定义为一个资源。这保证了整个应用程序只有一个实例,现在您可以使用staticresource引用这些设置。例如:

    <Application xmlns:myNS="clr-namespace:MyNamespace;assembly=MyAssembly" ...>
        <Application.Resources>
            <myNS:MySettings x:Key="Settings" />
        </Application.Resources>
    </Application>
    

    然后在windows/controls/templates/etc中,您可以使用以下方法访问mysettings实例:

    {Binding Source={StaticResource Settings}, Path=MyProperty}
    
        2
  •  4
  •   Jeremiah Morrill    15 年前

    可以使用XAML中的x:static,使用可以读取和绑定到的静态。我不喜欢做静态全局设置,因为它更像是反模式。

    我认为您应该研究控制/依赖注入的反转。外面有许多IOC容器,但我通常使用Unity进行依赖项注入。它在 http://prism.codeplex.com

    使用IOC,您可以注册设置类,并且在需要数据的虚拟机中,它们可以轻松地拉出您想要的设置。您的代码看起来与此类似(如果使用Unity)。

    var vm = container.Resolve<SomeViewModel>();
    
    public class SomeViewModel
    {
      public SomeViewModel(IUnityContainer container)
      {
          ISomeSettings settings = container.Resolve<ISomeSettings>();    
      }
    }
    

    编辑:或者您可能正在寻找另一个解决方案:

    创建您的单身:

    class GlobalSettings : ViewModel
    {
        private Thickness m_globalGirth;
    
        private static GlobalSettings m_instance = new GlobalSettings();
    
        public GlobalSettings()
        {
            GlobalGirth = new Thickness(2, 2, 2, 2);
        }
        public Thickness GlobalGirth
        {
            get { return m_globalGirth; }
            set
            {
                m_globalGirth = value;
                InvokePropertyChanged("GlobalGirth");
            }
        }
    
        public static GlobalSettings Instance
        {
            get { return m_instance; }
            set { m_instance = value; }
        }
    }
    

    然后设置绑定:

    <Window x:Class="WpfApplication3.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:WpfApplication3="clr-namespace:WpfApplication3"
        Title="Window1" Height="300" Width="300" MouseDoubleClick="Window_MouseDoubleClick">
        <Window.Resources>
            <WpfApplication3:GlobalSettings x:Key="settings" />
        </Window.Resources>
        <Grid>
            <Border BorderThickness="{Binding Source={StaticResource settings}, Path=Instance.GlobalGirth}"
                    BorderBrush="Black"
                    Width="100"
                    Height="100" />
        </Grid>
    </Window>