GlobalSettings ViewModel

时间:2009-10-05 09:02:50

标签: wpf mvvm settings

我有一些应该来自ViewModel的全局设置,并且应该可用于所有UserControl的所有DataTemplate。它包括GlobalButtonMargin,GlobalStrokeWidth或GlobalWorkspaceBackgroundColor之类的东西。这些东西都在viewmodel中,因为用户可以在运行时编辑这些设置。

您将如何以良好的MVVM方式实现此功能?

我考虑过使用Singleton GlobalSettingsViewModel。这是首选方法吗?如果是这样,我如何从XAML获取单例实例?

另一种方法是将GlobalSettings传递给我的应用程序中存在的所有ViewModel实例,以便我可以从我为其创建DataTemplates的视图模型中访问。但这感觉不洁净。

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

您能否勾勒出如何设计应用程序以支持此方案?

2 个答案:

答案 0 :(得分:4)

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

我认为你应该研究控制/依赖注入的反转。那里有许多IoC容器,但我通常使用Unity来进行依赖注入。它位于http://prism.codeplex.com

使用IoC,您可以注册设置类,并且在需要数据的VM中,他们可以轻松地提取您想要的设置。你的代码看起来与此类似(如果使用统一)。

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>

答案 1 :(得分:3)

我将创建类型以将ViewModel表示为类,然后将其实例定义为ApplicationLevel中的资源。这样可以保证整个应用程序的单个实例,现在您可以使用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}