C# Winforms DataGridView 选定单元格正在清除单元格值

Posted

技术标签:

【中文标题】C# Winforms DataGridView 选定单元格正在清除单元格值【英文标题】:C# Winforms DataGridView selected cell is clearing cell value 【发布时间】:2022-01-02 19:00:20 【问题描述】:

我正在开发一个预订系统。我正在使用多个 DGV 根据 DGV 中的 30 分钟插槽单元直观地显示不同房间的预订插槽,每个房间都有自己的 DGV。我在每个房间上使用了 foreach 语句来创建一个新的 DGV,适当地更改属性,为每个时间段添加行,如果它们与预订时间匹配,则在将其添加到 DGV 并将 DGV 添加到之前更改单元格颜色和值表格。

代码如下:

public partial class BookingSystem : Form

    List<string> RoomList = new List<string>();


    public BookingSystem()
    
        InitializeComponent();

        this.Text = "Booking System - " + DateTime.Today.DayOfWeek.ToString() + " " + DateTime.Today.ToString("dd MMM yyyy");

        RoomList.Add("Community Room 3");
        RoomList.Add("Community Room 2");
        RoomList.Add("Community Room 1");
        RoomList.Add("Sports Hall");
        //RoomList.Add("New Room");

        DateTime bookingStart = DateTime.Parse("23/11/2021 10:30:00");
        DateTime bookingStart2 = DateTime.Parse("23/11/2021 11:00:00");
        DateTime bookingEnd = DateTime.Parse("23/11/2021 11:30:00");

        this.Width = 1080;

        foreach (string room in RoomList)
        
            DataGridViewCellStyle dgvCellStyle = new DataGridViewCellStyle();
            Color color = Color.FromArgb(255, 224, 224, 224);
            dgvCellStyle.BackColor = color;

            DataGridView roomSchedule = new DataGridView();

            roomSchedule.Dock = DockStyle.Left;
            roomSchedule.Width = 200;
            roomSchedule.Columns.Add(room, room);
            roomSchedule.Columns[0].Width = 135;
            roomSchedule.RowHeadersWidth = 63;
            roomSchedule.AlternatingRowsDefaultCellStyle = dgvCellStyle;
            roomSchedule.RowHeadersBorderStyle = DataGridViewHeaderBorderStyle.Raised;
            roomSchedule.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
            //roomSchedule.ReadOnly = true;
            roomSchedule.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect;
            roomSchedule.AllowUserToResizeRows = false;

            DateTime openingTime = DateTime.Parse("07:00");
            DateTime closingTime = DateTime.Parse("22:00");
            TimeSpan openingHours = closingTime - openingTime;
            DateTime currentTimeSlot = openingTime;
            double totalRows = openingHours.TotalMinutes / 30;

            int rows = 0;

            while (rows <= totalRows)
            
                DataGridViewRow row = new DataGridViewRow();

                DataGridViewCellStyle bookedCellStyle = new DataGridViewCellStyle();
                bookedCellStyle.BackColor = Color.Moccasin;
                DataGridViewCell bookedCell = new DataGridViewTextBoxCell();
                bookedCell.Value = "Class Name";
                bookedCell.Style = bookedCellStyle;
                
                row.HeaderCell.Value = currentTimeSlot.ToString("HH:mm");
                roomSchedule.Rows.Add(row);
                
                if (currentTimeSlot.TimeOfDay == bookingStart.TimeOfDay || currentTimeSlot.TimeOfDay == bookingStart2.TimeOfDay)
                
                    if (room == "Sports Hall")
                    
                        row.Cells[0] = bookedCell;
                        //row.Cells[0].Value = "Class Name";
                    
                

                currentTimeSlot = currentTimeSlot.AddMinutes(30);

                roomSchedule.RowsDefaultCellStyle.SelectionBackColor = System.Drawing.Color.Transparent;
                rows++;
            
            
            dgvBox.Controls.Add(roomSchedule);
            
    

但是,当以这种方式输入单元格的值时,一旦选择了该单元格,该值就会被清除。

禁用 DGV 或将 DGV 行设为只读可以解决此问题,但我希望保留选择单元格的功能。

问题是通过使用 DataGridViewCellStyle.Value 设置单元格值产生的

bookedCell.Value = "Gravity ASD";

但我找不到任何其他方法来设置单元格值,如使用:

row.Cells[0].Value = "Class Name";

在将行添加到 DGV 之前,给我这个异常消息:Specified argument was out of the range of valid values

如果它在行之后添加到 DGV,它会给我这个异常消息:索引超出范围。必须是非负数且小于集合的大小

有没有办法以另一种方式将值添加到单元格,或者阻止所选单元格值被清除?

【问题讨论】:

【参考方案1】:

看来你可能让这变得比它必须的更复杂。然而;我可能不明白要求。经过一些小测试后,ODD 的突出之处在于代码将行添加到网格中的方式。从……开始

DataGridViewRow row = new DataGridViewRow(); … ? …

这很奇怪,它可能会起作用;但是,这是不必要的,而且它似乎会产生一些奇怪的行为,正如您所描述的那样。

我认为,既然您已经拥有 DataGridView ... roomSchedule WITH 列,那么您可能希望从“THAT GRID”中获取“NEW ROW”,而不是从头开始创建新行。像……

int rowIndex = roomSchedule.Rows.Add();
DataGridViewRow row = roomSchedule.Rows[rowIndex];

同样的想法也适用于行中的“CELL”。没有必要“创建”一个新的,因为我们从网格中得到的行已经有一个单元格。我希望这是有道理的。

DataGridViewCell bookedCell = row.Cells[0];

这些更改似乎使网格按预期运行。抱歉,如果我遗漏了什么,我希望这是有道理的。

【讨论】:

成功了,谢谢

以上是关于C# Winforms DataGridView 选定单元格正在清除单元格值的主要内容,如果未能解决你的问题,请参考以下文章

C# WinForms - DataGridView/SQL Compact - 主键列中的负整数

C# Winforms DataGridView 选定单元格正在清除单元格值

如何根据 c# winforms 中的列日期和名称将 sql 中的数据输入到特定的 datagridview 单元格中

带有按钮、组合框和文本框的 C# WinForms (.NET Framework) DataGridView:使用按钮添加新行以添加组合框项时出错

C# Winforms 中的 UI 渲染缓慢

(C#) 从 TextBox WinForms 的删除字符中获取索引