【问题标题】:C# Type Troubles - WPF Controlling a Main WindowC# 类型问题 - WPF 控制主窗口
【发布时间】:2017-07-06 07:12:35
【问题描述】:

我正在开发一个项目,该项目根据用户的角色向用户显示不同的主窗口。共有三个角色:学生、培训师和管理员。尽管每个角色的主窗口不同,但我希望能够在用户注销时调用 MainWindow.close(),而不考虑 MainWindow 的子类型。

当我尝试将 MainWindow 类的子类型(如 AdminMainWindow)分配给作为超级类型 MainWindow 键入的 mainWindow 变量时,我在 switch 语句中遇到了麻烦。

请告诉我如何设置我的类层次结构来完成这项工作。

namespace MVVM
{
    public partial class App : Application
    {
        LoginWindowViewModel loginWindowViewModel
        LoginWindow loginWindow; 

        MainWindowViewModel mainWindowViewModel
        MainWindow mainWindow;

        protected override void OnStartup(StartupEventArgs e)
        {
            setUpNewLoginWindow();
        }

        void setUpNewLoginWindow()
        { 
            loginWindowViewModel = new LoginWindowViewModel();

            loginWindowViewModel.UserIsAuthenticated += new EventHandler<LoginSuccessfulEventArgs>(loginWindowViewModel_UserIsAuthenticated);

            loginWindow = new LoginWindow(loginWindowViewModel);

            loginWindow.Show();
        }

        void loginWindowViewModel_UserIsAuthenticated(object sender, LoginSuccessfulEventArgs e)
        {
            User authenticatedUser = e.AuthenticatedUser;

            switch (authenticatedUser.Role)
            {
                case "A":
                    mainWindowViewModel = new AdminMainWindowViewModel(authenticatedUser);
                    mainWindow = new AdminMainWindow(adminMainWindowViewModel);
                    break;

                case "S":
                    mainWindowViewModel = new StudentMainWindowViewModel(authenticatedUser);
                    mainWindow = new StudentMainWindow(studentMainWindowViewModel);
                    break;

                case "T":
                    mainWindowViewModel = new TrainerMainWindowViewModel(authenticatedUser);
                    mainWindow = new TrainerMainWindow(trainerMainWindowViewModel);
                    break;

                default:
                    System.Diagnostics.Debug.WriteLine("This user does not have a role assigned.");
                    break;
            }

            mainWindow.Show();

            mainWindowViewModel.UserIsNotAuthenticated += new EventHandler(mainWindowViewModel_UserIsNotAuthenticated);

            loginWindowViewModel = null;

            loginWindow.Close();
        }

        void mainWindowViewModel_UserIsNotAuthenticated(object sender, EventArgs e)
        {
            setUpNewLoginWindow();

            mainWindowViewModel = null;

            mainWindow.Close();
        }
    }
}

****评论解决方案****

我试图做的是创建特定于用户登录角色的 Windows 和 ViewModel,但是一旦我构建了这些对象,我想对它们一视同仁,这样我就可以拥有 App 类听他们的“用户是未经身份验证的事件”并关闭窗口 - 无论我碰巧在应用程序的任何特定实例中创建的 ViewModel 和 Window 的类型。谢谢,康奈尔。

**** 修改后的代码 ****

using System;
using System.Windows;
using MVVM.Model;
using MVVM.Utility;
using MVVM.View.MainWindowsByRole;
using MVVM.ViewModel;

namespace MVVM
{
    public partial class App : Application
    {
        LoginWindowViewModel loginWindowViewModel;
        LoginWindow loginWindow;

        MainWindowViewModel mainWindowViewModel;
        Window mainWindow;

        protected override void OnStartup(StartupEventArgs e)
        {
            setUpNewLoginWindow();
        }

        void setUpNewLoginWindow()
        {
            loginWindowViewModel = new LoginWindowViewModel();

            loginWindowViewModel.UserIsAuthenticated += new EventHandler<LoginSuccessfulEventArgs>(loginWindowViewModel_UserIsAuthenticated);

            loginWindow = new LoginWindow(loginWindowViewModel);

            loginWindow.Show();
        }

        void loginWindowViewModel_UserIsAuthenticated(object sender, LoginSuccessfulEventArgs e)
        {
            User authenticatedUser = e.AuthenticatedUser;

            switch (authenticatedUser.Role)
            {
                case "A":
                    AdminMainWindowViewModel adminVM = new AdminMainWindowViewModel(authenticatedUser);
                    AdminMainWindow adminWindow = new AdminMainWindow(adminVM);
                    adminWindow.Show();
                    mainWindowViewModel = adminVM;
                    mainWindow = adminWindow;
                    break;

                case "S":
                    StudentMainWindowViewModel studentVM = new StudentMainWindowViewModel(authenticatedUser);
                    StudentMainWindow studentWindow = new StudentMainWindow(studentVM);
                    studentWindow.Show();
                    mainWindowViewModel = studentVM;
                    mainWindow = studentWindow;
                    break;

                case "T":
                    TrainerMainWindowViewModel trainerVM = new TrainerMainWindowViewModel(authenticatedUser);
                    TrainerMainWindow trainerWindow = new TrainerMainWindow(trainerVM);
                    trainerWindow.Show();
                    mainWindowViewModel = trainerVM;
                    mainWindow = trainerWindow;
                    break;

                default:
                    System.Diagnostics.Debug.WriteLine("This user does not have a role assigned.");
                    break;
            }

            mainWindowViewModel.UserIsNotAuthenticated += new EventHandler(mainWindowViewModel_UserIsNotAuthenticated);

            loginWindowViewModel = null;

            loginWindow.Close();
        }

        void mainWindowViewModel_UserIsNotAuthenticated(object sender, EventArgs e)
        {
            setUpNewLoginWindow();

            mainWindowViewModel = null;

            mainWindow.Close();
        }
    }
}

【问题讨论】:

  • 您到底在哪里遇到问题?鉴于代码看起来您​​只在用户通过身份验证时分配mainWindow
  • 在 switch 语句中使用 case 'A' - 当我构造一个新的 AdminMainWindow 并将其分配给 mainWindow 变量时出现错误。我得到的错误是编译器无法将 AdminMainWindow 对象隐式转换为 MainWindow 对象。 AdminMainWindow 继承自 MainWindow。也许我应该将我正在创建的 AdminMainWindow 对象转换为 MainWindow 对象,以便我可以将它存储在变量中?但我想也许我不需要这样做,因为继承。我确定这是我不明白的。

标签: c# inheritance mvvm types


【解决方案1】:

线

case "S":
    mainWindowViewModel = new StudentMainWindowViewModel(authenticatedUser);
    mainWindow = new StudentMainWindow(studentMainWindowViewModel);
    break;

执行从 StudentMainWindowViewModel 到 MainWindowViewModel 的隐式扩展转换。问题是您随后尝试在下一行中使用隐式转换进行缩小转换。 StudentMainWindow 构造函数需要 StudentMainWindowViewModel,但您传入的是 MainWindowViewModel。

请参阅此文档以获得更好的解释。

https://msdn.microsoft.com/en-us/library/k1e94s7e(v=vs.140).aspx

这也将提供信息。

Converting between types

你可以通过像这样修改你的代码来摆脱它:

switch (authenticatedUser.Role)
        {
            case "A":
                AdminMainWindowViewModel adminVM = new AdminMainWindowViewModel(authenticatedUser);
                mainWindowViewModel = adminVM;
                mainWindow = new AdminMainWindow(adminVM);
                break;

            case "S":
                StudentMainWindowViewModel studentVM = new StudentMainWindowViewModel(authenticatedUser);
                mainWindowViewModel = studentVM;
                mainWindow = new StudentMainWindow(studentVM);
                break;

            case "T":
                TrainerMainWindowViewModel trainerVM = new TrainerMainWindowViewModel(authenticatedUser);
                mainWindowViewModel = trainerVM;
                mainWindow = new TrainerMainWindow(trainerVM);
                break;

            default:
                System.Diagnostics.Debug.WriteLine("This user does not have a role assigned.");
                break;
        }

或者,您可以使用显式强制转换:

case "A":
    mainWindowViewModel = new AdminMainWindowViewModel(authenticatedUser);
    mainWindow = new AdminMainWindow((AdminMainWindowViewModel)mainWindowViewModel);
    break;

【讨论】:

  • 有趣,我没想到要像那样分解语句。我明天早上试试。我最近一直在更改此代码,因此对于案例之间存在一些不一致之处,我深表歉意。我希望意图是明确的。我会在测试你的想法后发布修改后的代码。
猜你喜欢
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-13
相关资源
最近更新 更多