我有一个带有列(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
我已经包含了该程序的屏幕转储信息。
John Hadley
答案 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