Datagridview comboboxcell 不会设置为 readonly = false

本文关键字:readonly false 设置 comboboxcell Datagridview | 更新日期: 2023-09-27 18:32:48

我有一个带有列(端口)的数据网格视图,我想用它来放置本地子网上计算机上的可用端口。 如果有一个或更少的端口,我使用文本框单元格 - 如果超过 1 个,我使用组合框单元格。 组合框单元格拒绝删除,只读属性拒绝为真。 在下面的代码中,您将看到我目前正在将列和单元格设置为只读 = true,但快速观察显示它仍然设置为 false。

我已经数不清我在代码或数据网格设置中尝试的变体数量。 我使用了数据绑定、组合框列以及此论坛和其他论坛上建议的许多版本的代码。

我可能正在做一些愚蠢的事情。 任何帮助将不胜感激。

        void AddRowFromScanSubnet(List<Machine> Machines)
    {
        dgComputers.Rows.Clear();
        lblItems.Text = Machines.Count.ToString();
        Machines.Sort(delegate (Machine x, Machine y)
        {
            if (x.ipaddress == null && y.ipaddress == null) return 0;
            else if (x.ipaddress == null) return -1;
            else if (y.ipaddress == null) return 1;
            else return x.ipaddress.CompareTo(y.ipaddress);
        });
        try
        {
            for (int i = 0; i < Machines.Count; i++)
            {
                string IPAddr = "Unknown";
                string MacAddr = "Unknown";
                string HostName = "Unknown";
                string Roll = "Unknown";
                List<string> PortList = new List<string>();
                string misc = "";
                string OS = "Unknown";
                string Status = "Unk";
                if (Machines[i].ipaddress != null) IPAddr = Machines[i].ipaddress;
                if (Machines[i].macaddress != null) MacAddr = Machines[i].macaddress;
                if (Machines[i].hostname != null) HostName = Machines[i].hostname;
                if (Machines[i].roll != null) Roll = Machines[i].roll;
                if (Machines[i].portlist != null) PortList = Machines[i].portlist;
                if (Machines[i].misc != null) misc = Machines[i].misc;
                if (Machines[i].OS != null) OS = Machines[i].OS;
                if (Machines[i].portlist != null) PortList = Machines[i].portlist;
                if (Machines[i].status != null) Status = Machines[i].status;
                if (PortList.Count == 0) PortList.Add("none");
                int number = dgComputers.Rows.Add();
                dgComputers.Rows[number].Cells[0].Value = IPAddr;
                dgComputers.Rows[number].Cells[1].Value = MacAddr;
                dgComputers.Rows[number].Cells[2].Value = HostName;
                dgComputers.Rows[number].Cells[3].Value = OS;
                dgComputers.Rows[number].Cells[4].Value = Roll;
                dgComputers.Columns[5].ReadOnly = false;
                if (PortList.Count < 2)
                {
                    dgComputers.Rows[number].Cells[5].Value = PortList[0];
                }
                else
                {
                    DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
                    c.MaxDropDownItems = 10;
                    foreach (string s in PortList)
                    {
                        c.Items.Add(s);
                    }
                    c.Value = PortList[0];
                    c.ReadOnly = false;
                    dgComputers.Rows[number].Cells[5] = c;
                    dgComputers.Rows[number].Cells[5].ReadOnly = false;
                }
                dgComputers.Columns[5].ReadOnly = false;
                dgComputers.Rows[number].Cells[6].Value = Status;
                dgComputers.Rows[number].Cells[7].Value = misc;
                dgComputers.Columns[5].ReadOnly = false;
                dgComputers.Rows[number].Cells[5].ReadOnly = false;
            }
        }
        catch (Exception ex)
        {
            string msg = "AddRowFromScanSubnet - " + ex.ToString();
        }
        Thread.Sleep(1000);
    }

数据网格视图列属性

我已经包含了该程序的屏幕转储以供参考。

程序的屏幕转储

约翰·哈德利

Datagridview comboboxcell 不会设置为 readonly = false

你的代码很好,但缺少一两件事:

DataGridViewCell只是一个稍微改进的对象。它不是一个Control,无论它支持哪种编辑风格。

事件 "简单"TextBoxCell只是实际TextBox的占位符。

系统对象
   System.Windows.Forms.DataGridViewElement
     System.Windows.Forms.DataGridViewCell

每种编辑样式的工作原理是将适当的编辑控件添加到DataGridViewControls集合中。您可以观察每当 DGV 进入编辑模式时如何添加一个控件。

并且要使该控件的工作方式与默认值提供的不同,您需要访问实际的编辑控件,而不是单元格!

为此,您需要对EditingControlShowing事件进行编码:

private void dgComputers_EditingControlShowing(object sender, 
                         DataGridViewEditingControlShowingEventArgs e)
{
    // mabye add checks to see if you want to make this one editable!?
    {
        ComboBox combo = e.Control as ComboBox;
        if (combo != null)  combo.DropDownStyle = ComboBoxStyle.DropDown;
    }
}

现在我们已经将ComboBoxStyleDropDownList更改为DropDown第 cell 是可编辑的。

通常,您希望保留输入的值;为此,请对CellValidating事件进行编码:

private void dgComputers _CellValidating(object sender,
                                         DataGridViewCellValidatingEventArgs e)
{
    // maybe add checks to see if this is the right one!?
    DataGridViewComboBoxCell comboCell =
        dgComputers[e.ColumnIndex, e.RowIndex] as DataGridViewComboBoxCell;
    if (comboCell != null)
        if (!comboCell.Items.Contains(e.FormattedValue))
            comboCell.Items.Add(e.FormattedValue);
}

正在为组合框分配一个值,而不是一个列表。

c.Items.AddRange(PortList.Cast<String>);代替c.Value = PortList[0]

两件事。

首先 - 我很尴尬。 整个网格已恢复为仅读取(不是几天前),所以我不确定我在过去几天尝试的任何事情是否会解决问题。 将 DataGridView 设置为 readonly = false 后,问题仍然存在。

第二 - TaW - 谢谢你的建议。 它似乎已经解决了我的问题。 我需要确保更改正确的单元格,但现在我有下拉组合框。 谢谢。

约翰·哈德利