Datagridview comboboxcell 不会设置为 readonly = false
Datagridview comboboxcell will not set to readonly = false
我有一个带有列(端口)的数据网格视图,我想用它来显示本地子网上机器上的可用端口。如果有一个或更少的端口,我使用文本框单元格 - 如果超过 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
我提供了该程序的屏幕转储以供参考。
约翰·哈德利
正在为组合框分配一个值,而不是一个列表。
使用
c.Items.AddRange(PortList.Cast<String>);
代替 c.Value = PortList[0]
您的代码很好,但缺少一两件事:
一个DataGridViewCell
只是一个稍微改进的对象。它不是Control
,无论它支持哪种编辑风格。
事件a 'simple' TextBoxCell
只是真正的TextBox
.
的占位符
System.Object
System.Windows.Forms.DataGridViewElement
System.Windows.Forms.DataGridViewCell
每个编辑样式都通过将适当的编辑控件添加到 DataGridView
的 Controls
集合来工作。当 DGV 进入编辑模式时,您可以观察如何添加一个控件。
并调整该控件使其工作方式不同于默认提供的控件,您需要访问实际的编辑控件,而不是单元格![=24=]
为此,您需要编写 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
事件代码:
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);
}
两件事。
首先 - 我很尴尬。整个网格已被设置回只读状态(不是几天前),所以我不确定过去几天我尝试过的任何事情是否能解决问题。将 DataGridView 设置为 readonly = false 后问题仍然存在。
其次 - TaW - 感谢您的建议。它看起来已经解决了我的问题。我需要确保更改了正确的单元格,但我现在有下拉组合框。谢谢。
约翰·哈德利
我有一个带有列(端口)的数据网格视图,我想用它来显示本地子网上机器上的可用端口。如果有一个或更少的端口,我使用文本框单元格 - 如果超过 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
我提供了该程序的屏幕转储以供参考。
约翰·哈德利
正在为组合框分配一个值,而不是一个列表。
使用
c.Items.AddRange(PortList.Cast<String>);
代替 c.Value = PortList[0]
您的代码很好,但缺少一两件事:
一个DataGridViewCell
只是一个稍微改进的对象。它不是Control
,无论它支持哪种编辑风格。
事件a 'simple' TextBoxCell
只是真正的TextBox
.
System.Object
System.Windows.Forms.DataGridViewElement
System.Windows.Forms.DataGridViewCell
每个编辑样式都通过将适当的编辑控件添加到 DataGridView
的 Controls
集合来工作。当 DGV 进入编辑模式时,您可以观察如何添加一个控件。
并调整该控件使其工作方式不同于默认提供的控件,您需要访问实际的编辑控件,而不是单元格![=24=]
为此,您需要编写 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
事件代码:
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);
}
两件事。
首先 - 我很尴尬。整个网格已被设置回只读状态(不是几天前),所以我不确定过去几天我尝试过的任何事情是否能解决问题。将 DataGridView 设置为 readonly = false 后问题仍然存在。
其次 - TaW - 感谢您的建议。它看起来已经解决了我的问题。我需要确保更改了正确的单元格,但我现在有下拉组合框。谢谢。
约翰·哈德利