WPF从具有MVVM的UserControl内部更改主窗口视图

时间:2016-06-22 07:33:40

标签: c# wpf xaml mvvm user-controls

我目前正在尝试学习WPF和MVVM模式,但在用户控件内部更改主窗口视图时感到困惑。

我目前拥有什么

我有一个单一的窗口应用程序,它在启动时显示一个登录视图,它是一个UserControl,并在我的主窗口中设置为ContentControl。

ApplicationView.xaml

    <Window x:Class="MyApplication.Views.ApplicationView"
        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:ignore="http://www.galasoft.ch/ignore"
        xmlns:local="clr-namespace:MyApplication.Views"
        xmlns:viewModels="clr-namespace:MyApplication.ViewModels"
        mc:Ignorable="d ignore"
        DataContext="{Binding Application, Source={StaticResource Locator}}">    
   <Window.Resources>
       <DataTemplate DataType="{x:Type viewModels:LoginViewModel }">
            <local:LoginView />
        </DataTemplate>
       <DataTemplate DataType="{x:Type viewModels:MainViewViewModel }">
           <local:MainView />
       </DataTemplate>
   </Window.Resources>
    <Grid>
        <ContentControl Content="{Binding CurrentPageViewModel}"></ContentControl>
    </Grid>
</Window>

ApplicationViewModel.cs

namespace MyApplication.ViewModels
{
    public class ApplicationViewModel : ViewModelBase
    {
        #region Fields

        private ICommand _changePageCommand;
        private IPageViewModel _currentPageViewModel;
        private List<IPageViewModel> _pageViewModels;

        #endregion

        public ApplicationViewModel()
        {
            //Add available pages
            PageViewModels.Add(new LoginViewModel());
            PageViewModels.Add(new MainViewViewModel());

            //Set starting page
            CurrentPageViewModel = PageViewModels[0];

        }

        #region Properties / Commands

        public ICommand ChangePageCommand
        {
            get
            {
                if (_changePageCommand == null)
                {
                    _changePageCommand = new RelayCommand<object>(
                        p => ChangeViewModel((IPageViewModel)p),
                        p => p is IPageViewModel);
                }

                return _changePageCommand;
            }
        }

        public List<IPageViewModel> PageViewModels
        {
            get
            {
                if (_pageViewModels == null)                
                    _pageViewModels = new List<IPageViewModel>();

                return _pageViewModels;
            }
        }

        public IPageViewModel CurrentPageViewModel
        {
            get
            {
                return _currentPageViewModel;
            }
            set
            {
                if (_currentPageViewModel != value)
                {
                    _currentPageViewModel = value;
                    this.VerifyPropertyName("CurrentPageViewModel");
                    this.RaisePropertyChanged();
                }
            }
        }

        #endregion


        #region Methods
        private void ChangeViewModel(IPageViewModel viewModel)
        {
            if (!PageViewModels.Contains(viewModel))
                PageViewModels.Add(viewModel);

            CurrentPageViewModel = PageViewModels
                .FirstOrDefault(vm => vm == viewModel);
        }
        #endregion
    }
}

我想要实现的目标

一旦点击登录UserControl中的登录按钮,我想将应用程序窗口视图从LoginView更改为MainView。我正在努力探讨如何实现这一目标以及如何实现这一目标。任何帮助将不胜感激,谢谢。

2 个答案:

答案 0 :(得分:0)

您只需执行Command ApplicationViewModel中的UserControl即可。请注意,ButtonUserControl需要在点击时在主窗口中切换视图,您可以按如下方式触发

<Button Command="{Binding DataContext.ChangePageCommand, RelativeSource=
          {RelativeSource AncestorType={x:Type ApplicationViewModel}}, Mode=OneWay}" />

如果您需要完整的工作示例,可以参考WPF MVVM navigate views

希望这有帮助。

答案 1 :(得分:0)

在Application View.xaml中:

<ContentControl Content="{Binding CurrentPageViewModel, Mode=TwoWay}"></ContentControl>

loginview.xaml 中,将登录按钮绑定到LoginViewModel内的命令LoginButtonClickedCommand

收听 ApplicationViewModel

中的命令
LoginViewModelInstance.LoginButtonClickedCommand = new RelayCommand(OnLoginButtonClicked, param => true);

处理命令处理程序并更改ApplicationViewModel中的CurrentPageViewModel

private void OnLoginButtonClicked(object obj)
{
    CurrentPageViewModel = new ContentPageViewModel();
}

这应该可以帮到你。