我已经阅读了几篇文章,教程,示例。但我仍然无法在页面和窗口之间进行导航。
> Visual Studio Community 2019
> .NET Framework: 4.7.2
为简单起见,我有 3 页和 1 个窗口 对于 KIOSK 应用程序,所有 View 都是全屏的 .详情页面如下:MVVMApps.sln
│
├── PageInitialize.xaml
├── PageHome.xaml
└──── PageSelectLanguage.xaml
└── WinMessage.xaml
我尝试了 GalaSoft 的 MvvmLight,但一直停留在 PageInitialize.xaml
的导航上。至PageHome.xaml
.我刚从 GalaSoft 找到文章WPF 即将推出 INavigationService
.我发现的大多数教程都是 Xamarin 的采样。另外,我得到了未定义的程序集
using Microsoft.Practices.ServiceLocation;
我看到它在 Enterprise 上可用。在 Nuget 上,安装 MvvmLight 也会安装 CommonServiceLocator。public class ViewModelLocator
{
private static bool initialized;
public ViewModelLocator()
{
//Fix to keep blend happy
if (initialized) { return; }
initialized = true;
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<PageInitializeViewModel>();
SimpleIoc.Default.Register<PageHomeViewModel>();
SimpleIoc.Default.Register<PageSelectLanguageViewModel>();
SimpleIoc.Default.Register<WinMessageViewModel>();
SetupNavigation();
}
public MainViewModel Main => ServiceLocator.Current.GetInstance<MainViewModel>();
public PageInitializeViewModel PageInitializeViewModel => ServiceLocator.Current.GetInstance<PageInitializeViewModel>();
public PageHomeViewModel PageHomeViewModel => ServiceLocator.Current.GetInstance<PageHomeViewModel>();
public WinMessageViewModel WinMessageViewModel=> ServiceLocator.Current.GetInstance<WinMessageViewModel>();
public static void Cleanup()
{
// TODO Clear the ViewModels
}
private void SetupNavigation()
{
var navigationService = new Helpers.NavigationService<Helpers.NavigationPage>();
navigationService.ConfigurePages();
SimpleIoc.Default.Register<Helpers.INavigationService<Helpers.NavigationPage>>(() => navigationService);
}
}
我已经完成了一些没有 MvvmLight 的教程:-每篇文章都使用不同的方法,由于我不熟悉它,一旦出现错误行并且没有 Intellisense 建议,我将无法继续找到解决方案。
如果我有多个页面和窗口屏幕,是否很难在 WPF 中使用 MVVM?目前,我有一个完整的 WPF 应用程序,但它使用代码隐藏。我想转向 MVVM,因为我已经读到 MVVM 比某处的代码隐藏更好。单页的 MVVM 不是我以前做过的问题,使用 MVVM 时它非常棒。
如果导航几乎不可能得到可行的答案,我是否应该保留在 WPF 中使用代码隐藏?
最佳答案
开始简单并设置navigationservice、viewmodellocators 和除基础之外的所有东西现在放在一边。
无论如何,我会避免所有那些....定位器类。他们必然依赖于反模式 IMO。
只需先使用 viewmodel 和单个窗口应用程序。
基本模式涉及一个 MainWindow,其 Datacontext 是 MainWindowViewModel。
您可能需要一个菜单或类似的菜单,但您要切换的部分是 contentcontrol 的内容。
将 ContentControl 的 Content 属性绑定(bind)到 mainwindowviewmodel 上的公共(public)对象属性。为讨论起见,调用该 CurrentViewModel。
每个 View 定义一个 View 模型和用户控件,您将在它们之间切换。因此 HomeView 和 HomeViewModel、LoginView 和 LoginViewModel。等等。
在资源字典中,为每个 View 创建一个数据模板,将您的用户控件与其 View 模型的类型相关联。
在 app.xaml 中合并此资源字典。
导航。
实例化您需要的那种新的 View 模型。
将 CurrentViewModel 设置为该实例。
然后它将被模板化到 UI 中。
这有很多变体——它首先被称为 View 模型,你应该能够轻松地在谷歌上搜索一些示例。
这是我写的一个稍微不同的目的:
https://social.technet.microsoft.com/wiki/contents/articles/52485.wpf-tips-and-tricks-using-contentcontrol-instead-of-frame-and-page-for-navigation.aspx
如果你真的想要页面,你可以对页面使用类似的方法:
简化 View :
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Window.Resources>
<DataTemplate DataType="{x:Type local:Page1ViewModel}">
<local:Page1/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Page2ViewModel}">
<local:Page2/>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListBox Name="ViewSelect"
ItemsSource="{Binding ViewChoices}"
SelectedItem="{Binding SelectedViewChoice, Mode=TwoWay}"
>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Frame Grid.Column="1"
Content="{Binding SelectedViewChoice.VM}"
NavigationUIVisibility="Hidden"
/>
</Grid>
</Window>
非常简化的 View 模型。 public class MainWindowViewModel : INotifyPropertyChanged
{
public ObservableCollection<ViewChoice> ViewChoices { get; set; }
= new ObservableCollection<ViewChoice>
{
new ViewChoice{ Name="Page One", VM=new Page1ViewModel()},
new ViewChoice{ Name="Page Two", VM=new Page2ViewModel()},
};
private ViewChoice selectedViewChoice;
public ViewChoice SelectedViewChoice
{
get { return selectedViewChoice; }
set { selectedViewChoice = value; RaisePropertyChanged(); }
}
ps如果你决定学习 prism,我会从 delegatecommand 开始,直到你写了至少一个 wpf 应用程序。
PRISM 中有大量的功能,大多数应用程序实际上并没有从区域和动态组合中受益。
如果您更喜欢 mvvmlight(我愿意),那么对于核心,您最好获取源代码并使用它。您需要 commandWPF 命名空间,这依赖于 nuget 包中的 net old。不支持命令的版本可以很好的执行requery。
我希望这是足够的信息而不是压倒性的。既要清楚又不要淹没有信息的人,这很棘手。
关于c# - 如何在 WPF 中使用 MVVM 在页面和打开的窗口之间导航?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63065795/