动机:
我想要一个'File->另存为'MenuItem
,其行为与Visual Studio中的行为相同。当没有任何东西打开时,它会显示“将所选项目另存为......”
当标签中打开特定文件(例如SomeFile.cs
)时,MenuItem
会将“SomeFile.cs
保存为...”。
我的应用架构(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
返回要在窗格标题中显示的字符串,
SafeFileName
仅返回路径的文件名等...
问题:
当我更改文件名(因此更改BaseProjectViewModel
的属性)时,如何触发RaisePropertyChanged
中SelectedProjectName
的{{1}}?
最干净的方法是什么?
我的想法
我想到了两种可能的方法,但我不知道它们中是否有正确的方法:
(简而言之)在MainWindowViewModel
上聆听CollectionChanged
。当有添加/删除 - &gt; subscribe / ubsubscribe一个事件处理程序
查看PropertyName是否是我们要查找的那个,如果是,则随后致电_projects
?
使用RaisePropertyChanged("SelectedProjectName")
。
问题2:如果您没有提出任何其他方式,事实上您会建议其中一种 - 请您详细说明优缺点?
修改
我创建了一个非常简单的项目来演示问题 - LINK。 运行项目时:
如果未选择TabItem,则{0}将解析为“选定项目”。
如果选择了一个选项卡,则单击SaveAs()并打开菜单,您将注意到尚未在SelectedProjectName属性上引发更改。当您单击另一个选项卡然后选择第一个选项卡时,将传播更改。
编辑Erno :我无法理解的是:我们假设每个文档类型都有一个特殊菜单。假设我选择了一个特定的选项卡(其自己的菜单已启用/可见,另一个已折叠)。它是如何帮助我将BaseProjectViewMode中的PaneHeader属性的PropertyChanged传播到MainWindowViewModel中的SelectedProjectName?如果您有时间,请在示例中进行演示吗?我还想问你,如果我想要/ neede做接线,会有什么替代方法?提前谢谢。
答案 0 :(得分:0)
根据您的选择,我不喜欢#1,因为它可能会引入很多难以跟踪和维护的布线。
选项#2可能没问题,但最终会出现与#1相同的布线混乱,但由于消息传递不太明显。
我会考虑另一种方法:
这样,您可以自定义每个文档的菜单(类型),并且不需要事件依赖性。