Datagridview comboboxcell不会设置为readonly = false

时间:2016-02-01 14:17:34

标签: c# winforms datagridview datagridviewcomboboxcell

我有一个带有列(Ports)的datagridview,我想用它来显示我本地子网上的机器上的可用端口。如果有一个或更少的端口,我使用文本框单元格 - 如果超过1,我使用组合框。组合框细胞拒绝丢弃,只读属性拒绝为真。在下面的代码中,您将看到我正在设置列,并且单元格为readonly = 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 column properties

我已经包含了该程序的屏幕转储信息。

Screen dump of program

John Hadley

3 个答案:

答案 0 :(得分:2)

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

DataGridViewCell只是略微改进的对象。它不是Control,无论它支持哪种编辑样式。

事件'简单'TextBoxCell只是真实TextBox的占位符。

  

System.Object
  System.Windows.Forms.DataGridViewElement
  System.Windows.Forms.DataGridViewCell

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

要调整该控件的工作方式与默认控件不同,您需要访问实际的编辑控件,而不是单元格!

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

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; } } ComboBoxStyle更改为DropDownList,则可以修改此单元格。

通常你想保留输入的值;这样做会对DropDown事件进行编码:

CellValidating

答案 1 :(得分:0)

组合框被赋予一个值,而不是列表。

使用

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

答案 2 :(得分:0)

两件事。

首先 - 我很尴尬。整个网格已经恢复到只读(这不是几天前),所以我不确定过去几天我尝试过的任何东西都能解决问题。将DataGridView设置为readonly = false后,问题仍然存在。

第二 - TaW - 谢谢你的建议。它看起来已经解决了我的问题。我需要确保更换正确的单元格,但我现在已经放下了组合框。谢谢。

John Hadley