代码之家  ›  专栏  ›  技术社区  ›  Rohit

在wpf mvvm中切换视图

  •  0
  • Rohit  · 技术社区  · 7 年前

    我有两个视图登录和用户模块。如果登录成功,我想切换到usermodule。我在主窗口中制作了数据模板和一个由currentviewmodel绑定的内容控件。我在MainWindowViewModel中创建了一个switchview方法,该方法在成功登录后调用。登录成功后,currentviewmodel将更改为usermoduleviewmodel,但视图没有更改。

    我是这样做的: MainWinodow。xaml

     <Window.Resources>
        <DataTemplate  DataType="{x:Type VM:LoginViewModel}">
            <local:LoginView></local:LoginView>
        </DataTemplate>
        <DataTemplate DataType="{x:Type VM:MenuViewModel}">
            <local:MenuWindow />
        </DataTemplate>
        <DataTemplate DataType="{x:Type VM:UserModuleMapViewModel}">
            <local:UserModuleMapView />
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ContentPresenter x:Name="Pages" Content="{Binding CurrentViewModel}" 
        Grid.Row="1"/>
    </Grid>
    

    主窗口。反恐精英

     MainWindowViewModel mainVM = new MainWindowViewModel();
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = mainVM;
    
        }
    

    MainWindowViewModel。反恐精英

    public class MainWindowViewModel : ViewModelBase
    {
        readonly LoginViewModel _loginViewModel = new LoginViewModel();
        readonly MenuViewModel _menuViewModel = new MenuViewModel();
        readonly UserModuleMapViewModel _usermodmapViewModel = new UserModuleMapViewModel();
    
        public MainWindowViewModel()
        {
            CurrentViewModel = _loginViewModel;
        }
    
        private ViewModelBase _currentViewModel;
    
        public ViewModelBase CurrentViewModel
        {
            get
            {
                return _currentViewModel;
            }
            set
            {
                if (_currentViewModel == value)
                    return;
                _currentViewModel = value;
                OnPropertyChanged("CurrentViewModel");
            }
        }
    
        public void switchView()
        {
            if (CurrentViewModel == _loginViewModel)
            {
                CurrentViewModel = _usermodmapViewModel;
            }
            else
            {
                CurrentViewModel = _loginViewModel;
            }
        }
    
    }
    

    LoginViewModel。反恐精英

    public LoginModel objmodel { get; set; }
        public ICommand LoginCommand { get; set; }
        public LoginModel _selectedItem { get; set; }
        public LoginModel SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                _selectedItem = value;
                OnPropertyChanged("comboBoxItems");//need to check now its working properly
            }
        }
    
        readonly UserModuleMapViewModel _usermodmapViewModel = new UserModuleMapViewModel();
    
        public LoginViewModel()
        {
            getjobkeycodeCombobox();
            objmodel = new LoginModel();
            LoginCommand = new RelayCommand(() => Login());
    
        }
     public void Login()
        {
            try
            {
                UserIdInfo info = new UserIdInfo();
    
                {
                    objmodel.job_Code_Key = SelectedItem.job_Code_Key;
                    info.EMP_NO = objmodel.EMP_NO;
                    info.Password = objmodel.Password;
                    info.Job_Code_Key = objmodel.job_Code_Key;
                    if (objmodel.EMP_NO == null || objmodel.EMP_NO == "" || objmodel.Password == null || objmodel.Password == "")
                    {
                        MessageBox.Show("Please Enter the inputs of all the fields..!!");
                    }
                    else
                    {
                        UserIdBL uidBL = new UserIdBL();
                        if (uidBL.isvalid(info))
                        {
                            MessageBox.Show("Success..!!");
    
                            MainWindowViewModel mwvm = new MainWindowViewModel();
                            mwvm.CurrentViewModel = _usermodmapViewModel;
                            //Messenger.Default.Send(new NotificationMessage("LoginSuccess"));
    
                        }
                        else
                        {
                        }
                    }
                }
            }
    
    
        }
    

    犯了什么错误?我是否遗漏了什么>

    2 回复  |  直到 7 年前
        1
  •  0
  •   Alex    7 年前

    ContentPresenter未更新的原因是视图绑定到的不同实例 MainWindowViewModel . 所以 MainWindow DataContext绑定到此处创建的实例:

    // MainWindow.cs
    MainWindowViewModel mainVM = new MainWindowViewModel();
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = mainVM;
    }
    

    LoginViewModel 创建的新实例 主窗口视图模型 不受任何约束:

    // LoginViewModel.cs
    MainWindowViewModel mwvm = new MainWindowViewModel();
    mwvm.CurrentViewModel = _usermodmapViewModel;
    

    这就是为什么当你 mwvm.CurrentViewModel 中的属性 Login 方法绑定未触发。

    因此,要实现您的目标,您可以订阅 主窗口视图模型 登录成功消息并在其中设置当前viewmodel。以下是MVVM Light messenger的一个简单示例:

    // LoginViewModel.cs
    if (uidBL.isvalid(info))
    {
        MessageBox.Show("Success..!!");
    
        // MainWindowViewModel mwvm = new MainWindowViewModel();
        // mwvm.CurrentViewModel = _usermodmapViewModel;
    
        // send message to all subscribers
        Messenger.Default.Send(new NotificationMessage("LoginSuccess"));
    }
    
    // MainWindowViewModel.cs
    Messenger.Default.Register<NotificationMessage>(this, (message) =>
    {
        switch (message.Notification)
        {
            case "LoginSuccess":
                CurrentViewModel = _usermodmapViewModel;
                break;
            default:
                break;
        }
    });
    
        2
  •  0
  •   Mal    7 年前

    一种可能的解决方案是使用Prism的IEventAggregator。您可以创建一个PubSub事件类,例如。

    公共类LoginSucessfulEvent:PubSubEvent{}

    然后使用事件聚合器的实例在主viewmodel中订阅该事件,例如。

    myEventAggregator。GetEvent()。订阅((obj)=>{somemethodinmainewmodel(obj);});

    然后,当登录成功时,从登录视图模型中发布事件,例如:。

    myEventAggregator。GetEvent()。发布(someLocalObject);

    我已经在我的一个项目中成功地使用了这个功能,但可能已经有6个月没有更新prism库了,但只要最新版本有这个功能,它就应该是好的。取决于项目中是否需要第三方库。

    您可以将操作传递给登录视图模型构造函数,该构造函数指向主视图模型上的方法,该方法将当前视图模型设置为主视图模型,并在登录成功时让登录视图模型调用该操作