You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 15:55:54