【问题标题】:WPF, MVVM and application wide resources best practicesWPF、MVVM 和应用程序范围的资源最佳实践
【发布时间】:2015-09-29 18:30:44
【问题描述】:

我目前正在编写一个 WPF 应用程序,它的左侧有一个导航面板(我绑定了一个 navigationViewModel),右侧有一个内容展示器(我绑定到前面提到的 VM 的 UserControl 成员“CurrentView”。 对于这个导航面板的每一项,我都创建了一个相应的用户控件,并为每个用户控件绑定了一个对应的 ViewModel 的实例。

单击导航面板的项目会将其 ViewModel 的 UserControl 成员 CurrentView 设置为相应 UC 的实例,然后将其显示在上述内容呈现器中。

第一个导航项是一些“选择或创建新客户”表单。完成此操作后,我想设置一些广泛的应用程序资源 ID,我会将其他导航项启用状态绑定到该 ID。因此,如果广泛的应用程序资源为空,则它们被禁用,一旦设置为任何值,它们就会被启用。还有一些机制可以让相应的 ViewModel 收到这种情况的通知。

我想知道这是否被认为是一种好习惯? 此外,我想知道我是否可以简单地在 app.xaml 中声明一个 int 资源并将其绑定到导航项 Enabled 属性,是否会将此资源设置为任何立即刷新此属性的内容?还是有更好、更简单或更清洁的方法?

【问题讨论】:

    标签: wpf mvvm inotifypropertychanged


    【解决方案1】:

    另一种方法是将两个视图模型(导航和当前视图)嵌套在第三个视图模型(比如主视图模型)中

    然后,这个主视图模型可以保持应该在这些视图模型和当前视图实例之间可用的状态。

    这样您就不需要在应用程序中拥有全局状态,您可以简单地将 Window 的数据上下文设置到主视图模型,并将导航和内容视图绑定到主视图模型的属性。

    这还允许您有一个适当的位置来导航到不同的内容视图。

    【讨论】:

    • 感谢您的回复让我思考!我发布了我最终做的事情,不知道它是否干净但它有效......
    【解决方案2】:

    这是我最终做的:

    在我的 app.xaml 中;我声明以下资源:

    <Application x:Class="MyProject.GUI.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:vm="clr-namespace:MyProject.GUI.ViewModels"
                 StartupUri="MainWindow.xaml">
        <Application.Resources>
            <vm:MainViewModel x:Key="MainViewModel" />
        </Application.Resources>
    </Application>
    

    此 MainViewModel 公开一个静态属性,如下所示:

    static bool _myStaticProperty;
    public static bool MyStaticProperty
    {
        get
        {
            return _myStaticProperty;
        }
        set
        {
            _myStaticProperty = value;
            NotifyStaticPropertyChanged("MyStaticProperty");
        }
    }
    

    还有如下静态INPC机制:

    #region Static property INPC mechanism
    public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;
    static void NotifyStaticPropertyChanged(string propertyName)
    {
        if (StaticPropertyChanged != null)
        {
            StaticPropertyChanged(null, new PropertyChangedEventArgs(propertyName));
        }
    }
    #endregion       
    

    还有我不同的视图模型:

    FirstChildViewModel _firstChildViewModel;
    public FirstChildViewModel FirstChildViewModel
    {
        get
        {
            if (_firstChildViewModel == null)
                _firstChildViewModel = new FirstChildViewModel();
            return _firstChildViewModel;
        }
    }
    //then a second one, a third one and so on
    

    绑定到我的用户控件如下

    <UserControl x:Class="MyProject.GUI.Views.FirstChildControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:MyProject.GUI.ViewModels"
             mc:Ignorable="d"
             DataContext="{Binding Path=FirstChildViewModel,
                                   Source={StaticResource MainViewModel}}">
    

    在我的用户控件的 xaml 代码中,我声明了命令绑定等,它们基本上在他们的 ViewModel 中执行以下操作

    MainViewModel.MyStaticProperty = myBoolValue;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-24
      • 2013-02-15
      • 2021-11-23
      • 1970-01-01
      • 2013-03-23
      • 2012-08-03
      • 2013-06-03
      • 2015-10-20
      相关资源
      最近更新 更多