动机:
我想要一个'File-> Save As'MenuItem
,其行为类似于Visual Studio。没有打开任何内容时,它说“将所选项目另存为...”
当在标签中打开特定文件(例如SomeFile.cs
)时,MenuItem
会显示“将SomeFile.cs
另存为...”。
我的App架构(MVVM
,使用MVVM Light
):
MainWindow.xaml:
<MenuItem Header="{Binding SelectedProjectName}" HeaderStringFormat="Save {0} As..." />
MainWindowViewModel:
我持有一些打开的标签页(打开的文件)
private ObservableCollection<BaseProjectViewModel> _projects;
我有一个属性返回当前选择的标签
public BaseProjectViewModel SelectedProject
{
get
{
return _selectedProject;
}
set
{
if (_selectedProject == value)
{
return;
}
_selectedProject = value;
RaisePropertyChanged("SelectedProject");
RaisePropertyChanged("SelectedProjectName");
}
}
我创建了一个属性,该属性返回当前选定选项卡中文件的名称
public string SelectedProjectName
{
get
{
if (SelectedProject == null)
{
return "Selected Item";
}
return SelectedProject.SafeFileName;
}
}
BaseProjectViewModel
充当各种文件类型的基类。每种文件类型都有自己的派生自BaseProjectViewModel
的类。它具有像PaneHeader
返回要在 Pane 标题中显示的字符串,SafeFileName
仅返回路径等的文件名...问题:
当我更改文件名(从而更改
BaseProjectViewModel
的属性)时,如何在RaisePropertyChanged
中触发SelectedProjectName
的MainWindowViewModel
?什么是最干净的方法?
我的想法
我想到了两种可能的方法,但是我不知道其中是否有正确的方法:
CollectionChanged
上听_projects
。当有添加/删除->订阅/ubsubscribe一个事件处理程序时,看看PropertyName是否是我们要寻找的那个,如果是,则随后调用
RaisePropertyChanged("SelectedProjectName")
? MVVM Light Messaging
的东西。 问题2:如果您不建议任何其他方式,而实际上却建议使用这两种方式中的一种-您能否详细说明优点和缺点?
编辑
我创建了一个非常简单的项目来演示问题LINK。
运行项目时:
当没有选择TabItem时,{0}解析为“Selected Item”。
选择一个选项卡后,单击SaveAs()并打开菜单,您会注意到尚未对SelectedProjectName属性进行更改。当您单击另一个选项卡,然后选择第一个选项卡时,更改将被传播。
为Erno编辑:我无法理解的是:假设我对每种文档类型都有一个特殊的菜单。假设我选择了一个特定的选项卡(启用/可见了其自己的菜单,另一个处于折叠状态)。如何帮助我将BaseProjectViewMode中PaneHeader属性的PropertyChanged传播到MainWindowViewModel中的SelectedProjectName?如果有时间,可以在示例中进行演示吗?我也想问你,如果我想/需要做布线,那是另一种选择?先感谢您。
最佳答案
根据您的选择,我不喜欢#1,因为它可能会引入很多难以跟踪和维护的布线。
选项#2可能还可以,但最终可能会导致与#1相同的布线困惑,但由于消息传递,它的可见性将降低。
我会考虑另一种方法:
这样,您可以针对每个文档(类型)自定义菜单,并且不需要事件相关性。
关于c# - 在不同类中的Property上引发PropertyChangeNotification(不同的ViewModel),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18460779/