WPF RoomId传递异常:任务无法展示且新增任务失败
WPF任务管理系统RoomId传递异常问题
问题现象
- 选择房间后切换至RoomView窗口,无任务数据显示
- 点击新增任务按钮时提示RoomId为0,任务创建失败
- 初始化RoomView时通过MessageBox验证RoomId已正确传递,但点击按钮时RoomId变为0
相关代码
打开RoomView的命令代码
private void ExecuteShowRoomViewCommand(object obj) { RoomWindow roomWindow = new RoomWindow(); if (roomWindow.ShowDialog() == true || roomWindow.IsRoomCreated) { RoomView roomView = new RoomView(roomWindow.RoomId); CurrentChildView = new RoomViewModel(); Caption = roomWindow.RoomName; Icon = PackIconKind.Class; } }
RoomWindow类代码
namespace TaskManagement { /// <summary> /// Interaction logic for RoomWindow.xaml /// </summary> public partial class RoomWindow : Window { string connectionString = "Data Source=DESKTOP-FTLJ7LQ\\MSSQLS;Initial Catalog=TaskManagement;Integrated Security=True;"; public bool IsRoomCreated { get; private set; } = false; public string RoomName { get; private set; } public string AccessCode { get; private set; } public int RoomId { get; private set; } public RoomWindow() { InitializeComponent(); LoadUserRooms(); } private void LoadUserRooms() { try { using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); string query = @"SELECT Room.RoomId, Room.RoomName FROM Room INNER JOIN RoomUser ON Room.RoomId = RoomUser.RoomId WHERE RoomUser.UserId = @UserId"; using (SqlCommand command = new SqlCommand(query, connection)) { command.Parameters.AddWithValue("@UserId", MainWindow.CurrentUserId); using (SqlDataReader reader = command.ExecuteReader()) { List<Room> rooms = new List<Room>(); while (reader.Read()) { rooms.Add(new Room { RoomId = reader.GetInt32(0), RoomName = reader.GetString(1) }); } RoomListBox.ItemsSource = rooms; } } } } catch (Exception ex) { MessageBox.Show($"An error occurred while loading rooms: {ex.Message}"); } } private void RoomListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (RoomListBox.SelectedItem is Room selectedRoom) { RoomId = selectedRoom.RoomId; RoomName = selectedRoom.RoomName; MessageBox.Show($"Room selected: {RoomName}"); MessageBox.Show($"Room selected: {RoomId}"); MessageBox.Show($"Room selected: {MainWindow.CurrentUserId}"); IsRoomCreated = true; this.Close(); } } private void JoinRoomButton_Click(object sender, RoutedEventArgs e) { string accessCode = AccessCodeTextBox.Text.Trim(); if (string.IsNullOrWhiteSpace(accessCode)) { MessageBox.Show("Please enter the access code."); return; } try { using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); string query = @"SELECT Room.RoomId, Room.RoomName FROM Room INNER JOIN AccessCode ON Room.AccessCodeId = AccessCode.AccessCodeId WHERE AccessCode.AccessCode = @AccessCode AND AccessCode.ExpirationDate > GETDATE()"; using (SqlCommand command = new SqlCommand(query, connection)) { command.Parameters.AddWithValue("@AccessCode", accessCode); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { RoomId = reader.GetInt32(0); RoomName = reader.GetString(1); MessageBox.Show($"You have joined the room: {RoomName}"); IsRoomCreated = true; // Adding record to RoomUser table AddUserToRoom(RoomId, MainWindow.CurrentUserId); this.Close(); } else { MessageBox.Show("Invalid access code or the code has expired."); } } } } } catch (Exception ex) { MessageBox.Show($"An error occurred while joining the room: {ex.Message}"); } } private void CreateRoomButton_Click(object sender, RoutedEventArgs e) { RoomName = RoomNameTextBox.Text.Trim(); // Ensure no extra spaces if (!string.IsNullOrWhiteSpace(RoomName)) { AccessCode = GenerateAccessCode(); try { using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); // Insert AccessCode into AccessCode table string insertAccessCodeQuery = @"INSERT INTO AccessCode (AccessCode, DateGenerated, ExpirationDate) OUTPUT INSERTED.AccessCodeId VALUES (@AccessCode, @DateGenerated, @ExpirationDate)"; using (SqlCommand command = new SqlCommand(insertAccessCodeQuery, connection)) { command.Parameters.AddWithValue("@AccessCode", AccessCode); command.Parameters.AddWithValue("@DateGenerated", DateTime.Now); command.Parameters.AddWithValue("@ExpirationDate", DateTime.Now.AddDays(30)); // For example, the code is valid for 30 days int accessCodeId = (int)command.ExecuteScalar(); // Insert Room into Room table string insertRoomQuery = "INSERT INTO Room (RoomName, AccessCodeId) VALUES (@RoomName, @AccessCodeId)"; using (SqlCommand roomCommand = new SqlCommand(insertRoomQuery, connection)) { roomCommand.Parameters.AddWithValue("@RoomName", RoomName); roomCommand.Parameters.AddWithValue("@AccessCodeId", accessCodeId); roomCommand.ExecuteNonQuery(); } } } IsRoomCreated = true; MessageBox.Show($"Room '{RoomName}' created with access code: {AccessCode}"); this.Close(); } catch (Exception ex) { MessageBox.Show($"An error occurred while creating the room: {ex.Message}"); } } else { MessageBox.Show("Please enter the room name."); } } private string GenerateAccessCode() { // Generate access code const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; var random = new Random(); var result = new StringBuilder(8); // Access code length is 8 characters for (int i = 0; i < 8; i++) { result.Append(chars[random.Next(chars.Length)]); } return result.ToString(); } private void AddUserToRoom(int roomId, int userId) { try { using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); string insertRoomUserQuery = "INSERT INTO RoomUser (RoomId, UserId, RoleId) VALUES (@RoomId, @UserId, @RoleId)"; using (SqlCommand command = new SqlCommand(insertRoomUserQuery, connection)) { command.Parameters.AddWithValue("@RoomId", roomId); command.Parameters.AddWithValue("@UserId", userId); command.Parameters.AddWithValue("@RoleId", 1); // Role "user" (assuming user role ID is 1) command.ExecuteNonQuery(); } } } catch (Exception ex) { MessageBox.Show($"An error occurred while adding the user to the room: {ex.Message}"); } } } }
RoomView类代码
namespace TaskManagement { /// <summary> /// Interaction logic for RoomView.xaml /// </summary> public partial class RoomView : UserControl { private string connectionString = "Data Source=DESKTOP-FTLJ7LQ\\MSSQLS;Initial Catalog=TaskManagement;Integrated Security=True;"; public int RoomId { get; set; } public RoomView() { InitializeComponent(); DataContext = this; } public RoomView(int roomId) : this() { RoomId = roomId; List<RoomTask> taskItems = LoadData(roomId); dataGridTask1.ItemsSource = taskItems; } private List<RoomTask> LoadData(int roomId) { List<RoomTask> taskList = new List<RoomTask>(); using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); string sqlQuery = @"SELECT RoomTask.TaskId, RoomTask.TaskName, RoomTask.TaskDateCreation, RoomTask.TaskDateCompletion, RoomTask.TaskPriority, RoomTask.TaskStatus, Project.ProjectName FROM RoomTask INNER JOIN Project ON RoomTask.ProjectId = Project.ProjectId WHERE RoomTask.RoomId = @RoomId"; using (SqlCommand command = new SqlCommand(sqlQuery, connection)) { command.Parameters.AddWithValue("@RoomId", roomId); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { RoomTask taskItem = new RoomTask { TaskId = Convert.ToInt32(reader["TaskId"]), TaskName = reader["TaskName"].ToString(), TaskDateCreation = Convert.ToDateTime(reader["TaskDateCreation"]), TaskDateCompletion = reader["TaskDateCompletion"] != DBNull.Value ? Convert.ToDateTime(reader["TaskDateCompletion"]) : (DateTime?)null, TaskPriority = reader["TaskPriority"].ToString(), TaskStatus = reader["TaskStatus"].ToString(), Project = new ProjectItem { ProjectName = reader["ProjectName"].ToString() } }; taskList.Add(taskItem); } } } } return taskList; } private void AddTaskButton_Click(object sender, RoutedEventArgs e) { if (RoomId == 0) { MessageBox.Show("Invalid room ID."); return; } string taskName = textBoxTaskName.Text.Trim(); if (string.IsNullOrWhiteSpace(taskName)) { MessageBox.Show("Please enter the task name."); return; } try { using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); string query = @"INSERT INTO RoomTask (TaskName, TaskDateCreation, TaskPriority, TaskStatus, ProjectId, RoomId) VALUES (@TaskName, @TaskDateCreation, @TaskPriority, @TaskStatus, @ProjectId, @RoomId)"; using (SqlCommand command = new SqlCommand(query, connection)) { command.Parameters.AddWithValue("@TaskName", taskName); command.Parameters.AddWithValue("@TaskDateCreation", DateTime.Now); command.Parameters.AddWithValue("@TaskPriority", "Medium"); command.Parameters.AddWithValue("@TaskStatus", "In Progress"); command.Parameters.AddWithValue("@ProjectId", GetSelectedProjectId()); command.Parameters.AddWithValue("@RoomId", RoomId); command.ExecuteNonQuery(); } } List<RoomTask> taskItems = LoadData(RoomId); dataGridTask1.ItemsSource = taskItems; textBoxTaskName.Clear(); } catch (Exception ex) { MessageBox.Show($"An error occurred while adding the task: {ex.Message}"); } } private int GetSelectedProjectId() { // Returns the ID of the selected project, here you need to implement the logic to get ProjectId return 1; // Example } private void textBoxTaskName_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) { if (e.Key == System.Windows.Input.Key.Enter) { AddTaskButton_Click(sender, e); } } } }
问题分析与修复
核心问题
在ExecuteShowRoomViewCommand方法中,虽然创建了携带正确RoomId的RoomView实例,但并未将其赋值给CurrentChildView,反而给CurrentChildView赋值了一个全新的RoomViewModel实例。这导致界面实际渲染的是一个未初始化RoomId的ViewModel,而非你创建的RoomView控件,最终出现任务不显示、新增任务时RoomId为0的问题。
修复代码
修改ExecuteShowRoomViewCommand方法,将创建好的RoomView实例直接赋值给CurrentChildView:
private void ExecuteShowRoomViewCommand(object obj) { RoomWindow roomWindow = new RoomWindow(); if (roomWindow.ShowDialog() == true || roomWindow.IsRoomCreated) { RoomView roomView = new RoomView(roomWindow.RoomId); // 将带RoomId的RoomView实例赋值给CurrentChildView CurrentChildView = roomView; Caption = roomWindow.RoomName; Icon = PackIconKind.Class; } }
额外建议
如果项目采用MVVM模式,建议将RoomId等业务数据放到RoomViewModel中,通过ViewModel管理数据逻辑,而不是直接在UserControl中处理数据库操作。这样可以更好地分离视图与业务逻辑,提升代码可维护性。
内容的提问来源于stack exchange,提问作者Hezee
相关产品推荐
相关产品推荐

