【发布时间】:2019-12-10 11:28:44
【问题描述】:
我是 WPF 和 MVVM 的新手(来自 WinForms 和 Events),所以请多多包涵!
我试图弄清楚如何在多个视图之间使用相同的INotifyPropertyChanged 值绑定。我正在使用 MVVM Light。我有从 ViewModelBase 继承的 ViewModels 支持我的视图(没有后面的代码)。我不知道如何解释这个问题,但我认为一个例子可以清楚地说明我所追求的。
我有一个主窗口。它有一个标准的TabControl。在登录 TabItem 我有一个自定义登录控件。在TabControl 下方,我有一个自定义状态栏控件。期望的行为是,当用户登录时,状态栏会更新他们的登录状态和名称,并且主窗口上的其他 TabItems 会启用(未登录时应该禁用它们)。
总结一下,我有:
- MainWindow(视图)与 MainWindowViewModel
- 使用 LoginViewModel 登录(查看)(在 MainWindow 的
TabControl中) - StatusBar(视图)和 StatusBarViewModel(位于 MainWindow 底部)
这是我的StatusBarViewModel 的样子:
public class StatusBarViewModel : ViewModelBase, IStatusBarViewModel
{
private bool _isLoggedIn;
public bool IsLoggedIn
{
get { return _isLoggedIn; }
set { Set(ref _isLoggedIn, value); RaisePropertyChanged(); }
}
// other properties follow
}
我通过构造函数注入(使用 Ninject)将IStatusBarViewModel 的(单例)具体实例注入 LoginViewModel:
public class LoginViewModel : ViewModelBase
{
private IStatusBarViewModel _statusBar;
public LoginViewModel(IStatusBarViewModel statusBar)
{
_statusBar = statusBar;
}
}
我对 MainWindowViewModel 做同样的事情:
public class MainWindowViewModel : ViewModelBase
{
private IStatusBarViewModel _statusBar;
public bool IsLoggedIn => _statusBar.IsLoggedIn;
public MainWindowViewModel(IStatusBarViewModel statusBar)
{
_statusBar = statusBar;
}
}
注意:我认为这是我的问题所在......不确定 MVVM Light 是否将其解释为可绑定属性并应用正确的更改通知。如果我添加一个 setter(我在这里不需要),那将不起作用,因为 A property or indexer may not be passed as an out or ref parameter。所以我不清楚当我这样做时发生了什么。
回到正轨,所以当登录成功时,我可以像这样从LoginViewModel 更新IsLoggedIn 属性:
_statusBar.IsLoggedIn = true;
我在我的 MainWindow XAML 中设置绑定,如下所示:
<TabItem Header="Event" IsEnabled="{Binding IsLoggedIn}">
<views:Events/>
</TabItem>
第一次加载视图时绑定正常工作,但随后对属性的更改不会触发IsEnabled 的更改。但是,状态栏(视图)会相应更新。
我曾考虑将 StatusBarViewModel 和 MainWindowViewModel 的引用注入到我的 LoginViewModel 中(然后必须在登录后设置两个属性),但这让我认为我没有正确处理这个问题,因为我'正在创建依赖项。
所以基本上问题是:
- 按照 MVVM 模式,我的方法是否正确?
- 我是否走在正确的轨道上,只需要稍微修改一下代码吗?
- 如果不是,处理这种情况的(或一种)标准模式是什么?
【问题讨论】:
标签: c# wpf mvvm data-binding mvvm-light