我有 3 个视图模型(AdminViewModel、StudentViewModel、ProfessorViewModel),我有一个用户登录数据库的 UI,我创建了一个名为 ExtractRole 的方法,它扮演当前从数据库登录的用户的角色。我正在尝试为了在用户登录后完成他的角色,并根据角色调用并可视化三个 ViewModel 之一。我不知道如何“绑定”ViewModel,以便可以调用它
这就是我制作 LoginView.xaml.cs 的方式 ”
public partial class LoginView : Window
{
private string _databasePath;
public LoginView()
{
InitializeComponent(); _databasePath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Welcome.db");
}
private bool isLoggedIn = false;
private void LoginBtn_Click(object sender, RoutedEventArgs e)
{
// Perform validation against the database
bool isValidUser = ValidateUser(LoginTextBox.Text, PasswordTextBox.Password);
if (!isLoggedIn)
{
if (isValidUser)
{
// Navigate to the StudentsList page
string role = ExtractRole(LoginTextBox.Text, PasswordTextBox.Password);
MessageBox.Show($"Your role is: {role}");
StudentsList studentsList = new StudentsList();
// Add the StudentsList UserControl to a container (e.g., a Grid)
// Assuming you have a Grid called "mainGrid" defined in your LoginView.xaml
mainGrid.Children.Clear(); // Clear existing content
mainGrid.Children.Add(studentsList);
isLoggedIn = true;
LoginBtn.Content = "Exit"; // Change button text to "Exit"
}
else
{
MessageBox.Show("Invalid username or password! Please try again!");
}
}
else
{
isLoggedIn = false;
// Optionally, you can open a new instance of the login window
LoginView loginView = new LoginView();
loginView.Show();
// Close the current window
Window.GetWindow(this).Close();
LoginBtn.Content = "Login"; // Change button text to "Login"
}
// Prevent the button click event from bubbling up and closing the window
e.Handled = true;
}
// Method to validate user credentials (dummy implementation)
private bool ValidateUser(string username, string password)
{
// Construct the connection string to the SQLite database
string connectionString = $"Data Source={_databasePath};";
using (SqliteConnection connection = new SqliteConnection(connectionString))
{
connection.Open();
// SQL query to check if the provided username and password exist in the Users table
string query = "SELECT COUNT (*) FROM Users WHERE Name = @Name AND Password = @Password";
// Create a command object with the query and connection
using (SqliteCommand command = new SqliteCommand(query, connection))
{
// Add parameters to the query to prevent SQL injection
command.Parameters.AddWithValue("@Name", username);
command.Parameters.AddWithValue("@Password", password);
long result = (long)command.ExecuteScalar();
int count = Convert.ToInt32(result);
connection.Close();
return count > 0;
}
}
}
private string ExtractRole(string username, string password)
{
string role = null;
string connectionString = $"Data Source={_databasePath};";
using (SqliteConnection connection = new SqliteConnection(connectionString))
{
connection.Open();
string query = "SELECT Role FROM Users WHERE Name = @Name AND Password =@Password";
using (SqliteCommand command = new SqliteCommand(query, connection))
{
command.Parameters.AddWithValue("@Name", username);
command.Parameters.AddWithValue("@Password", password);
object roleObject = command.ExecuteScalar();
if(roleObject != null)
{
role = roleObject.ToString();
}
}
}
return role;
}
}
这是我的 StudentViewModel 的例子: ”
namespace Welcome.ViewModel
{
public class StudentViewModel: UserViewModel
{
private Model.User _user;
public StudentViewModel(Model.User user) : base(user)
{
_user = user;
}
public StudentGradeStatus GradeStatus
{
get {return _user.GradeStatus;}
set{_user.GradeStatus = value; }
}
public DateTime BirthDay
{
get { return _user.BirthDay; }
set { _user.BirthDay = value; }
}
public string FNomer
{
get { return _user.FNomer; }
set { _user.FNomer = value; }
}
public UserGender Gender
{
get { return _user.Gender; }
set { _user.Gender = value; }
}
}
我尝试在 LoginView.xaml 中使用:
xmlns:local1="clr-namespace:Welcome.ViewModel;assembly=Welcome"
<Window.Resources>
<DataTemplate DataType="{x:Type local1:AdminViewModel}">
<local1:StudentViewModel/>
</DataTemplate>
但收到:” 严重性代码 说明 项目文件行抑制状态 错误 XLS0414 未找到类型“local1:ProfessorViewModel”。验证您没有缺少程序集引用并且所有引用的程序集均已构建。”
在您的 xaml 中,您需要定义在提供特定视图模型时应使用的视图。这看起来像:
<DataTemplate DataType="{x:Type local1:AdminViewModel"}">
<local1:MyViewForAll/>
</DataTemplate>
<DataTemplate DataType="{x:Type local1:StudentViewModel"}">
<local1:MyViewForAll/>
</DataTemplate>
<DataTemplate DataType="{x:Type local1:ProfessorViewModel"}">
<local1:MyViewForAll/>
</DataTemplate>
要显示内容,我将使用 ContentControl,它绑定到一个对象或所有 3 个不同 ViewModel 共享的基类。
<ContentControl Content="{Binding CurrentViewModel}" x:Name="mainContent"/>
在视图模型或代码隐藏中,您可以根据登录的用户类型将正确的 ViewModelType 分配给 ContentControl。这可能类似于:
switch(role)
{
case "admin":
CurrentViewModel = new AdminViewModel();
break;
case "professor":
CurrentViewModel = new ProfessorViewModel();
break;
case "student":
CurrentViewModel = new StudentViewModel();
break;
default:
throw new ArgumentException("case not found");
}