【发布时间】:2020-10-07 08:32:57
【问题描述】:
我有一个 MainWindowViewModel,我的 MainWindow 包含一个显示项目页面的框架。 显示的第一页是最近打开的项目列表(类似于 Microsoft Word),它有自己的 ViewModel。 加载列表没有问题,但是当我想将此列表中的用户选择的项目发送到 MainWindowViewModel 时,我无法使用 Find-Ancestor 到达 Window DataContext(看起来框架有一些限制)。
如何将用户选择的项目发送到 MainWindowViewModel?
public class RecentlyOpenedFilesViewModel
{
readonly IFileHistoryService _fileHistoryService;
private ObservableCollection<RecentlyOpenedFileInfo> _RecentlyOpenedFilesList;
public ObservableCollection<RecentlyOpenedFileInfo> RecentlyOpenedFilesList
{
get { return _RecentlyOpenedFilesList; }
set { _RecentlyOpenedFilesList = value; RaisePropertyChanged(); }
}
public RecentlyOpenedFilesViewModel( IFileHistoryService fileService):base()
{
_fileHistoryService = fileService;
RecentlyOpenedFilesList=new ObservableCollection<RecentlyOpenedFileInfo>(_fileHistoryService.GetFileHistory());
}
public void RefreshList()
{
RecentlyOpenedFilesList = new ObservableCollection<RecentlyOpenedFileInfo>(_fileHistoryService.GetFileHistory());
}
}
<Page
x:Class="MyProject.Views.V3.Other.RecentlyOpenedFilesPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyProject.Views.V3.Other"
xmlns:vmv3="clr-namespace:MyProject"
Title="RecentlyOpenedFilesPage">
<Page.Resources>
<DataTemplate x:Key="RecentlyOpenedFileInfoTemplate"
>
<Button
Height="70"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}, Path=DataContext.OpenProjectFromPathCommand}"
CommandParameter="{Binding}">
<Button.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="70" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<StackPanel
Grid.Row="0"
Grid.Column="0"
VerticalAlignment="Top">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Path}" />
</StackPanel>
<TextBlock
Grid.Row="0"
Grid.Column="1"
Margin="50,0,0,0"
VerticalAlignment="Center"
Text="{Binding DateModified}" />
</Grid>
</Button.Content>
</Button>
</DataTemplate>
</Page.Resources>
<Grid>
<ListView
ItemTemplate="{StaticResource RecentlyOpenedFileInfoTemplate}"
ItemsSource="{Binding RecentlyOpenedFilesList}" />
</Grid>
public RecentlyOpenedFilesPage(MainWindowViewModel vm)
{
this.DataContext = vm;
InitializeComponent();
}
现在我在 MainWindowViewModel 和 RecentOpenedFilesViewModel 之间建立了直接链接,但我想删除这种依赖关系并使用另一种连接方式,例如(我遇到问题的路由命令) MainWindow 包含一个框架,在该框架中将 RecentOpenedFilesPage 设置为其内容。
<Window
x:Class="MyProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:fw="clr-namespace:SourceChord.FluentWPF;assembly=FluentWPF" >
<Frame Name="frameMain"/></Window>
public class MainWindowViewModel : RecentlyOpenedFilesViewModel, IMainWindowViewModel
{
private void LoadRecentlyOpenedProjects()
{
CurrentView = new RecentlyOpenedFilesPage(this);
}
}
【问题讨论】:
-
没有足够的代码来理解相关部分是如何协同工作的
-
感谢您的回复,@grek40 我试图提供更多代码,如果我可以提供更多详细信息,请告诉我。
-
既然您将页面
DataContext设置为MainWindowViewModel,那么您在哪里设置RecentlyOpenedFilesViewModel?另外,看看page.DataContext not inherited from parent Frame?,可能是相关的 -
我从 RecentOpenedFilesViewModel 继承了 MainWindowViewMoel,我知道这不是解决方案,但它确实有效。我将继承添加到其余代码中
-
抱歉,当您的视图模型知道您在
CurrentView = new RecentlyOpenedFilesPage(this);中的视图时,您没有使用 MVVM 模式。与 MVVM 模式的这种偏差使您很难理解您的应用程序是如何工作的。
标签: c# wpf mvvm viewmodel mainwindow