c# - 根据使用 MVVM 从视图模型读取的数据库打开视图选择
问题描述
在我的 WPF MVVM 项目中,我有一些表单和一个保存员工信息的数据库。有一个员工视图模型,这有一个employeeId
传递给它,使用员工模型,员工的详细信息是从数据库中读取的。这也会读取员工是“用户”还是“管理员”。
然后视图模型将决定加载哪个视图。用户视图或管理员视图。这两个视图之间有很多相似之处,这就是为什么我对两者都使用相同的视图模型。
这就是为什么对于我的项目,我决定保持一致并让我的视图模型打开它们的视图。但是,在网上研究我只能看到实例化视图的建议,然后在视图构造函数中创建视图模型。
我的方法是 MVVM 的错误方法吗?我将如何以正确的方式处理这种情况?
主窗口视图模型:
public void OpenSelectedEmployee(object employee)
{
if (employee == null)
return;
StaffListModel model = (StaffListModel)employee;
EmployeeViewModel vm = new EmployeeViewModel(model.EmployeeId);
}
员工视图模型:
private EmployeeModel employee;
private Window employeeWindow;
// Employee View Model Constructor
public EmployeeViewModel(int employeeId)
{
// Connect to DB and read data for employee class
if (LoadEmployee(employeeId))
{
if (employee.UserType == "User")
employeeWindow = new EmployeeUserDetailsView();
else // if Admin
employeeWindow = new EmployeeAdminDetailsView();
employeeWindow.DataContext = this;
employeeWindow.ShowDialog();
}
else
{
// Open error message
MessageBox.Show("Error loading employee occurred");
}
}
我已经考虑将用户类型存储在主窗口视图模型中,以便决定打开哪个视图。但是,如果由于某种原因数据库无法读取员工 ( LoadEmployee(employeeId)
),则创建视图毫无意义,我希望显示错误消息框。
编辑:这是LoadEmployee
目前的方法EmployeeViewModel
。它在构造函数中使用,并通过绑定按钮刷新表单。
public bool LoadEmployee(int employeeId)
{
if (!DbConnector.OpenDB())
return false;
try
{
employee = EmployeeModel.FindById(employeeId);
Depots = DepotModel.FindAllShort();
Departments = EmployeeModel.FindAllDepartments();
TenureHistory = TenureHistoryModel.FindAllByEmployeeId(employeeId);
IdCards = IdCardModel.FindAllByEmployeeId(employeeId);
Qualifications = QualificationModel.FindAllByEmployeeId(employeeId);
TheoryBookings = TheoryBookingModel.FindAllByEmployeeId(employeeId);
MedicalRecords = MedicalRecordModel.FindAllByEmployeeId(employeeId);
EyesightChecks = EyesightCheckModel.FindAllByEmployeeId(employeeId);
}
catch
{
DbConnector.CloseDB();
return false;
}
DbConnector.CloseDB();
return true;
}
public void Refresh(object parameter)
{
if (!LoadEmployee(employee.EmployeeId))
MessageBox.Show("An error has occurred");
NotifyPropertyChanged(string.Empty);
}
解决方案
从视图模型创建或引用视图或窗口违反并有效地破坏了 MVVM 设计模式。
您应该为您注入MainWindowViewModel
一个IWindowService
负责创建窗口的实现:
public class WindowService : IWindowService
{
public void ShowDialog(EmployeeViewModel viewModel, EmployeeModel model)
{
if (LoadEmployee(model.employeeId))
{
Window employeeWindow;
if (model.UserType == "User")
employeeWindow = new EmployeeUserDetailsView();
else // if Admin
employeeWindow = new EmployeeAdminDetailsView();
employeeWindow.DataContext = viewModel;
employeeWindow.ShowDialog();
}
else
{
// Open error message
MessageBox.Show("Error loading employee occurred");
}
}
}
主窗口视图模型:
private readonly IWindowService _windowService;
public MainWindowViewModel(IWindowService windowService)
{
_windowService = windowService;
}
public void OpenSelectedEmployee(object employee)
{
if (employee == null)
return;
StaffListModel model = (StaffListModel)employee;
EmployeeViewModel vm = new EmployeeViewModel(model.EmployeeId);
_windowService.ShowDialog(vm, model);
}
在此处查看我的答案以获取另一个示例。
推荐阅读
- php - 如何将 instanceof 运算符与抽象类一起使用?
- flutter - 改变'未来
' 为条件转换为静态类型 'bool' - node.js - 有没有办法在 AWS Lambda 中修改环境变量?
- php - UPSERT BigQuery
- html - 字段的数据验证
- javascript - 在引导标记字段中复制粘贴电子邮件在 IE 中不起作用
- android - Firebase 云消息推送通知在 Android Kitkat 上不起作用
- drupal-8 - 在我的 drupal 站点上安装 drush 时,drush 将显示错误
- xcode - dyld:找不到符号:___chkstk_darwin
- reactjs - 眼镜代码幻灯片扩展不起作用