从MVVM中的UserControl内部导航ContentControl



我正在尝试在不使用第三方框架的情况下创建一种ShellView,并且我正在尝试通过来实现这一点。ContentControls和UserControls。

只要命令是从UserControls外部激发的,我就可以导航/切换显示在ContentControls内部的UserControls,但当我将代码移动到UserControl中的按钮内部时,什么都不会发生。

目前我有一个MainWindow.XAML,其中有一个ContentControl。

此ContentControl承载LoginDowUserControl或UserWindowUserControl-我希望能够从其中一个UserControl中切换UserControl。

我的主窗口.XAML如下所示:

<Window x:Class="ModelHealthApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vms="clr-namespace:ModelHealthApplication.ViewModels"
xmlns:ia="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:views="clr-namespace:ModelHealthApplication.Views.UserControls"
xmlns:local="clr-namespace:ModelHealthApplication"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<DataTemplate DataType="{x:Type vms:CurrentWindowUserStateViewModel}">
<views:UserView />
</DataTemplate>
<DataTemplate DataType="{x:Type vms:LoginWindowViewModel}">
<views:LoginView />
</DataTemplate>
<vms:NavigationViewModel x:Key="nVm" />
</Window.Resources>
<ia:Interaction.Triggers>
<ia:EventTrigger EventName="Loaded">
<ia:InvokeCommandAction Command="{Binding Source={StaticResource nVm}, Path=OpenLoginWindowCommand}" />
</ia:EventTrigger>
</ia:Interaction.Triggers>
<Grid DataContext="{StaticResource nVm}">
<DockPanel>
<Button Content="Test" DockPanel.Dock="Left" Command="{Binding OpenUserWindowStateCommand}" />
<ContentControl x:Name="WindowUserState" Content="{Binding CurrentWindowUserState}" />
</DockPanel>
</Grid>

我的UserWindowUserControl看起来是这样的:

<UserControl x:Class="ModelHealthApplication.Views.UserControls.UserView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:vms="clr-namespace:ModelHealthApplication.ViewModels"
xmlns:views="clr-namespace:ModelHealthApplication.Views.UserControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:local="clr-namespace:ModelHealthApplication.Views.UserControls"
mc:Ignorable="d" 
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<DataTemplate DataType="{x:Type vms:MyModelsViewModel}">
<views:MyModelsView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vms:MyAccountViewModel}">
<views:MyAccountView />
</DataTemplate>
<vms:NavigationViewModel x:Key="nVm" />
</UserControl.Resources>
<Grid>
<DockPanel DataContext="{StaticResource nVm}">
<Grid DockPanel.Dock="Top" Background="{StaticResource MainBlue}" Height="25">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.Column="0">
<Button Content="My Models" 
HorizontalAlignment="Center" 
Command="{Binding OpenMyModelsCommand}"
Style="{StaticResource NavButtonStyle}"/>
<Button Content="My Account" 
HorizontalAlignment="Center" 
Command="{Binding OpenMyAccountCommand}"
Style="{StaticResource NavButtonStyle}"
/>
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Right" Grid.Column="1" Margin="0, 0, 10, 0">
<TextBlock  VerticalAlignment="Center" Foreground="White">
<Run Text="Logged in as:" FontWeight="Bold"/>
<Run Text="{Binding LoggedInAs}" d:Text="TestUser" />
</TextBlock>
<TextBlock Margin="20, 0 ,0 ,0" Text="Log Out"  VerticalAlignment="Center" TextDecorations="Underline" Foreground="{StaticResource ComplenetarySecondOrange}" Background="{DynamicResource MainBlue}" Cursor="Hand">
<TextBlock.InputBindings>
<MouseBinding Command="{Binding OpenLoginWindowCommand}" MouseAction="LeftClick" />
</TextBlock.InputBindings>
</TextBlock>
</StackPanel>
</Grid>
<ContentControl x:Name="Pages" Content="{Binding SelectedViewModel}" />
</DockPanel>
</Grid>
</UserControl>

当我按下";注销";button/textblock我想导航回登录窗口,但我只能通过UserControl之外的按钮来完成。

我读过其他几篇类似的帖子,但我还没有找到适合我需求的解决方案——我尝试过使用RelativeSource,但没有成功——也许有人能看出我做错了什么。

我正在使用一个";NavigationViewModel";保存命令,正如我所提到的,在UserControls:之外运行良好

using ModelHealthApplication.Commands;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace ModelHealthApplication.ViewModels
{
public class NavigationViewModel : INotifyPropertyChanged
{
public ICommand OpenMyModelsCommand { get; set; }
public ICommand OpenMyAccountCommand { get; set; }
public ICommand OpenUserWindowStateCommand { get; set; }
public ICommand OpenLoginWindowCommand { get; set; }
private object currentWindowUserState;
public object CurrentWindowUserState
{
get { return currentWindowUserState; }
set 
{ 
currentWindowUserState = value;
OnPropertyChanged("CurrentWindowUserState");
}
}
private object selectedViewModel;
public object SelectedViewModel
{
get { return selectedViewModel; }
set 
{ 
selectedViewModel = value;
OnPropertyChanged("SelectedViewModel");
}
}
public NavigationViewModel()
{
OpenMyModelsCommand = new OpenMyModelsCommand(this);
OpenMyAccountCommand = new OpenAccountCommand(this);
OpenUserWindowStateCommand = new OpenUserWindowStateCommand(this);
OpenLoginWindowCommand = new OpenLoginWindowCommand(this);
}
public void OpenUserWindowState(object obj)
{
CurrentWindowUserState = new CurrentWindowUserStateViewModel();
}
public void OpenLoginWindow(object obj)
{
CurrentWindowUserState = new LoginWindowViewModel();
}
public void OpenMyModels(object obj)
{
SelectedViewModel = new MyModelsViewModel();
}
public void OpenMyAccount(object obj)
{
SelectedViewModel = new MyAccountViewModel();
}

public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
}

通过Youtube上SingletonSean的精彩教程解决了这个问题。

如果有人遇到这个问题,并且有同样的问题,请在这里发帖。

Singleton Sean MVVM Navigatoin

最新更新