C# 使用MVVM(无代码隐藏)和不带导航的按钮单击更改视图

C# 使用MVVM(无代码隐藏)和不带导航的按钮单击更改视图,c#,wpf,wcf,xaml,mvvm,C#,Wpf,Wcf,Xaml,Mvvm,我正在使用WPF MVVM 我有一个WCF聊天服务,它应该执行某些验证操作(用户凭据),以便向聊天窗口发送消息 这当然是在我按下“登录”按钮时发生的 我想要完成的是在我按下login键并且验证成功的那一刻创建一个新的视图(聊天窗口视图) *由于我还没有聊天视图,让我们假设我的聊天视图是我的注册视图(只是为了了解如何使用ICommand在按钮单击上切换视图) 我将发布我所做的: MainWindow.xaml: <Window.Resources> <DataTe

我正在使用WPF MVVM

我有一个WCF聊天服务,它应该执行某些验证操作(用户凭据),以便向聊天窗口发送消息

这当然是在我按下“登录”按钮时发生的

我想要完成的是在我按下login键并且验证成功的那一刻创建一个新的视图(聊天窗口视图)

*由于我还没有聊天视图,让我们假设我的聊天视图是我的注册视图(只是为了了解如何使用ICommand在按钮单击上切换视图)

我将发布我所做的:

MainWindow.xaml:

    <Window.Resources>
    <DataTemplate DataType="{x:Type  ViewModels:LoginViewModel}">
        <Views:LoginView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type ViewModels:SignUpViewModel}">
        <Views:SignUpView />
    </DataTemplate>
</Window.Resources>
<Grid>
    <ContentControl Content="{Binding CurrentView}" />
</Grid>
LoginViewModel.cs

    public class LoginViewModel : ViewModelBase
{
    public AuthenticatedUser AuthenticatedUser { get; set; }
    private string username;

    public string UserName
    {
        get { return username; }
        set {
            username = value;
            Notify();
        }
    }
    private string password;
    public string Password
    {
        get { return password; }
        set
        {
            password = value;
            Notify();
        }
    }

    public ConsoleLog ConsoleLog { get ; set; } // TODO: StringBuilder.
    public UserServiceProxy UserServiceProxy { get; set; }
    public ChatServiceProxy ChatServiceProxy { get; set; }

    public LoginViewModel()
    {
        AuthenticatedUser = AuthenticatedUser.Instance;
        UserServiceProxy = new UserServiceProxy();
        ChatServiceProxy = new ChatServiceProxy();
        SendLoginRequestCommand = new MyCommand(SendLoginRequest);
        ConsoleLog = new ConsoleLog();
        ConsoleLog.Document = "Binding Checker.";
    }

    public ICommand SendLoginRequestCommand { get; set; }

    private void SendLoginRequest()
    {
      LoginResponse response = UserServiceProxy.Login(new LoginRequest { UserName = UserName, Password = Password });
        ConsoleLog.Document += $"{response.IsSuccess} {response.Message}";
      if(response.IsSuccess == true)
        {
            AuthenticatedUser.Authentication = response.Authentication;
            JoinServiceResponse responseFromChatService = ChatServiceProxy.JoinService(new JoinServiceRequest());
            ConsoleLog.Document += responseFromChatService.Message;

            /* This is where I think the view should be changed,yet no success for a few days now.
             * 
             * 
             * 
             * 
             * 
             */
        }

    }

    private void LoginEventRaised(object sender, OnLoginEventArgs e)
    {
        ConsoleLog.Document += $"{e.UserName} has logged in.";
    }
}
SignUpViewModel.cs:

    public class SignUpViewModel : ViewModelBase
{
    public string UserName { get; set; }
    public string Password { get; set; }
    public string PasswordConfirm { get; set; }
    public ConsoleLog ConsoleLog { get; set; }
    public UserServiceProxy UserServiceProxy { get; set; }

    public ICommand OnClickSignUpCommand { get; set; }

    public SignUpViewModel()
    {
        UserServiceProxy = new UserServiceProxy();
        ConsoleLog = new ConsoleLog { Document = "Check Register."};
        OnClickSignUpCommand = new MyCommand(SendSignUpRequest);
    }

    private void SendSignUpRequest()
    {
      SignUpResponse response = UserServiceProxy.SignUp(new SignUpRequest { UserName = UserName, Password = Password, PasswordConfirm = PasswordConfirm });
        if(response.IsSuccess == true)
        {
            ConsoleLog.Document += $"{response.IsSuccess} {response.Message}";
            response.AllOtherUsers.ForEach(u => ConsoleLog.Document += $"{u.UserName} Signed up.");
        }
    }
}
    public class AppViewModel : ViewModelBase
{
    private ViewModelBase currentView;

    public ViewModelBase CurrentView
    {
        get { return currentView; }
        set {
            currentView = value;
            Notify();
        }
    }

    public ICommand ViewLoginCommand { get; }
    public ICommand ViewSignUpCommand { get; }

    public AppViewModel()
    {
        ViewLoginCommand = new MyCommand(SetCurrentViewToLoginViewModel);
        ViewSignUpCommand = new MyCommand(SetCurrentViewToSignUpViewModel);
        CurrentView = new LoginViewModel(); //temporary loading the first view the use will see.
    }
    private void SetCurrentViewToLoginViewModel()
    {
        CurrentView = new LoginViewModel();
    }
    public void SetCurrentViewToSignUpViewModel()
    {
        CurrentView = new SignUpViewModel();
    }
}
ViewModelBase.cs:

    public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public virtual void Notify([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
AppViewModel.cs:

    public class SignUpViewModel : ViewModelBase
{
    public string UserName { get; set; }
    public string Password { get; set; }
    public string PasswordConfirm { get; set; }
    public ConsoleLog ConsoleLog { get; set; }
    public UserServiceProxy UserServiceProxy { get; set; }

    public ICommand OnClickSignUpCommand { get; set; }

    public SignUpViewModel()
    {
        UserServiceProxy = new UserServiceProxy();
        ConsoleLog = new ConsoleLog { Document = "Check Register."};
        OnClickSignUpCommand = new MyCommand(SendSignUpRequest);
    }

    private void SendSignUpRequest()
    {
      SignUpResponse response = UserServiceProxy.SignUp(new SignUpRequest { UserName = UserName, Password = Password, PasswordConfirm = PasswordConfirm });
        if(response.IsSuccess == true)
        {
            ConsoleLog.Document += $"{response.IsSuccess} {response.Message}";
            response.AllOtherUsers.ForEach(u => ConsoleLog.Document += $"{u.UserName} Signed up.");
        }
    }
}
    public class AppViewModel : ViewModelBase
{
    private ViewModelBase currentView;

    public ViewModelBase CurrentView
    {
        get { return currentView; }
        set {
            currentView = value;
            Notify();
        }
    }

    public ICommand ViewLoginCommand { get; }
    public ICommand ViewSignUpCommand { get; }

    public AppViewModel()
    {
        ViewLoginCommand = new MyCommand(SetCurrentViewToLoginViewModel);
        ViewSignUpCommand = new MyCommand(SetCurrentViewToSignUpViewModel);
        CurrentView = new LoginViewModel(); //temporary loading the first view the use will see.
    }
    private void SetCurrentViewToLoginViewModel()
    {
        CurrentView = new LoginViewModel();
    }
    public void SetCurrentViewToSignUpViewModel()
    {
        CurrentView = new SignUpViewModel();
    }
}
LoginView.xaml(这是一个用户控件):


SignUpView.xaml(此问题实际上不需要此代码,只是以防万一):


我知道我错过了一些东西。可能是因为我花了几天时间试图解决这个问题,所以我迷失了方向

这是我的登录名:(还不能嵌入)

当我按下“登录”按钮时,我需要加载下一个视图:

我不能为这个问题提供任何代表。尽管如此,我还是非常感谢你的帮助


浏览了网络,找不到合适的问题。

您的问题中确实提供了很多代码,请参见此 在发布问题之前

如果我了解您在程序中尝试执行的操作,则您的
AppViewModel
是您的“MainNavigation”类,负责管理所有视图并在它们之间导航

我可以为您提供的一个解决方案是在
LoginViewModel
中添加一个事件,当用户成功登录时将引发该事件。在您的
AppViewModel
中,您将注册到此事件并实现一个处理程序,该处理程序将
CurrentView
属性更改为您的
SignUpViewModel

添加到
LoginViewModel.cs
的内容如下所示:

public class LoginViewModel : ViewModelBase
{
    ...

    public delegate void UserLoginSuccessfullyHandler();
    public event UserLoginSuccessfullyHandler UserLoginSuccessfullyEvent;

    private void SendLoginRequest()
    {
      LoginResponse response = UserServiceProxy.Login(new LoginRequest { UserName = UserName, Password = Password });
        ConsoleLog.Document += $"{response.IsSuccess} {response.Message}";
      if(response.IsSuccess == true)
        {
            AuthenticatedUser.Authentication = response.Authentication;
            JoinServiceResponse responseFromChatService = ChatServiceProxy.JoinService(new JoinServiceRequest());
            ConsoleLog.Document += responseFromChatService.Message;

            // This is where you inform the AppViewModel to change his CurrentView
            if (UserLoginSuccessfullyEvent!= null)
                UserLoginSuccessfullyEvent();
        }
    }

    ...
}
    public class AppViewModel : ViewModelBase
{
    ...

    public AppViewModel()
    {
        var loginViewModel = new LoginViewModel();
        loginViewModel.UserLoginSuccessfullyEvent += new UserLoginSuccessfullyHandler(myUserLoginSuccessfullyHandler);
        CurrentView = loginViewModel;
    }

    private void myUserLoginSuccessfullyHandler()
    {
        CurrentView = new SignUpViewModel();
    }

    ...
}
添加到AppViewModel.cs的内容如下所示:

public class LoginViewModel : ViewModelBase
{
    ...

    public delegate void UserLoginSuccessfullyHandler();
    public event UserLoginSuccessfullyHandler UserLoginSuccessfullyEvent;

    private void SendLoginRequest()
    {
      LoginResponse response = UserServiceProxy.Login(new LoginRequest { UserName = UserName, Password = Password });
        ConsoleLog.Document += $"{response.IsSuccess} {response.Message}";
      if(response.IsSuccess == true)
        {
            AuthenticatedUser.Authentication = response.Authentication;
            JoinServiceResponse responseFromChatService = ChatServiceProxy.JoinService(new JoinServiceRequest());
            ConsoleLog.Document += responseFromChatService.Message;

            // This is where you inform the AppViewModel to change his CurrentView
            if (UserLoginSuccessfullyEvent!= null)
                UserLoginSuccessfullyEvent();
        }
    }

    ...
}
    public class AppViewModel : ViewModelBase
{
    ...

    public AppViewModel()
    {
        var loginViewModel = new LoginViewModel();
        loginViewModel.UserLoginSuccessfullyEvent += new UserLoginSuccessfullyHandler(myUserLoginSuccessfullyHandler);
        CurrentView = loginViewModel;
    }

    private void myUserLoginSuccessfullyHandler()
    {
        CurrentView = new SignUpViewModel();
    }

    ...
}
你可以在这里看到更多关于事件的信息
.

您的问题中确实提供了很多代码,请参见此 在发布问题之前

如果我了解您在程序中尝试执行的操作,则您的
AppViewModel
是您的“MainNavigation”类,负责管理所有视图并在它们之间导航

我可以为您提供的一个解决方案是在
LoginViewModel
中添加一个事件,当用户成功登录时将引发该事件。在您的
AppViewModel
中,您将注册到此事件并实现一个处理程序,该处理程序将
CurrentView
属性更改为您的
SignUpViewModel

添加到
LoginViewModel.cs
的内容如下所示:

public class LoginViewModel : ViewModelBase
{
    ...

    public delegate void UserLoginSuccessfullyHandler();
    public event UserLoginSuccessfullyHandler UserLoginSuccessfullyEvent;

    private void SendLoginRequest()
    {
      LoginResponse response = UserServiceProxy.Login(new LoginRequest { UserName = UserName, Password = Password });
        ConsoleLog.Document += $"{response.IsSuccess} {response.Message}";
      if(response.IsSuccess == true)
        {
            AuthenticatedUser.Authentication = response.Authentication;
            JoinServiceResponse responseFromChatService = ChatServiceProxy.JoinService(new JoinServiceRequest());
            ConsoleLog.Document += responseFromChatService.Message;

            // This is where you inform the AppViewModel to change his CurrentView
            if (UserLoginSuccessfullyEvent!= null)
                UserLoginSuccessfullyEvent();
        }
    }

    ...
}
    public class AppViewModel : ViewModelBase
{
    ...

    public AppViewModel()
    {
        var loginViewModel = new LoginViewModel();
        loginViewModel.UserLoginSuccessfullyEvent += new UserLoginSuccessfullyHandler(myUserLoginSuccessfullyHandler);
        CurrentView = loginViewModel;
    }

    private void myUserLoginSuccessfullyHandler()
    {
        CurrentView = new SignUpViewModel();
    }

    ...
}
添加到AppViewModel.cs的内容如下所示:

public class LoginViewModel : ViewModelBase
{
    ...

    public delegate void UserLoginSuccessfullyHandler();
    public event UserLoginSuccessfullyHandler UserLoginSuccessfullyEvent;

    private void SendLoginRequest()
    {
      LoginResponse response = UserServiceProxy.Login(new LoginRequest { UserName = UserName, Password = Password });
        ConsoleLog.Document += $"{response.IsSuccess} {response.Message}";
      if(response.IsSuccess == true)
        {
            AuthenticatedUser.Authentication = response.Authentication;
            JoinServiceResponse responseFromChatService = ChatServiceProxy.JoinService(new JoinServiceRequest());
            ConsoleLog.Document += responseFromChatService.Message;

            // This is where you inform the AppViewModel to change his CurrentView
            if (UserLoginSuccessfullyEvent!= null)
                UserLoginSuccessfullyEvent();
        }
    }

    ...
}
    public class AppViewModel : ViewModelBase
{
    ...

    public AppViewModel()
    {
        var loginViewModel = new LoginViewModel();
        loginViewModel.UserLoginSuccessfullyEvent += new UserLoginSuccessfullyHandler(myUserLoginSuccessfullyHandler);
        CurrentView = loginViewModel;
    }

    private void myUserLoginSuccessfullyHandler()
    {
        CurrentView = new SignUpViewModel();
    }

    ...
}
你可以在这里看到更多关于事件的信息