向我的 DataGridView 添加新行时出现异常
Exception when adding a new row to my DataGridView
我有这个问题。开头是这样的:
我可以双击下拉箭头并选择一种颜色确定:
此时,我可以再次点击下拉菜单,它被正确选中了:
问题是我想添加一个新行。即使我只是去点击新的行单元格:
然后我数据一个数据错误异常:
此后上一个单元格绘制不正确:
我不太明白如何解决这个问题。
我的代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using Teigha.Core;
using Teigha.TD;
namespace Viewer
{
public partial class Editor : Form
{
uint[] _CurPalette = Teigha.Core.AllPalettes.getDarkPalette();
public Editor()
{
InitializeComponent();
}
private void Editor_Load(object sender, EventArgs e)
{
DataGridViewComboBoxColumn cboColumn = new DataGridViewComboBoxColumn();
cboColumn.Name = "Color";
List<ushort> listColors = new List<ushort>();
listColors.Add(1);
listColors.Add(2);
listColors.Add(3);
listColors.Add(4);
listColors.Add(5);
listColors.Add(6);
listColors.Add(7);
listColors.Add(8);
listColors.Add(9);
listColors.Add(250);
listColors.Add(251);
listColors.Add(252);
listColors.Add(253);
listColors.Add(254);
listColors.Add(255);
foreach (ushort iColorIndex in listColors)
{
using (OdCmColor oColor = new OdCmColor())
{
oColor.setColorIndex(iColorIndex);
ComboboxColorItem oColorItem = new ComboboxColorItem(
oColor.colorNameForDisplay(),
iColorIndex,
Color.FromArgb(oColor.red(), oColor.green(), oColor.blue()));
cboColumn.Items.Add(oColorItem);
}
}
this.DataGridView1.Columns.Add(cboColumn);
}
private void DataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is ComboBox)
{
ComboBox theCB = (ComboBox)e.Control;
theCB.DrawMode = DrawMode.OwnerDrawFixed;
try
{
theCB.DrawItem -= new DrawItemEventHandler(this.combobox1_DrawItem);
}
catch { }
theCB.DrawItem += new DrawItemEventHandler(this.combobox1_DrawItem);
}
}
private void combobox1_DrawItem(object sender, DrawItemEventArgs e)
{
Graphics g = e.Graphics;
Color c = Color.Empty;
string s = "";
Brush br = SystemBrushes.WindowText;
Brush brBack;
Rectangle rDraw;
bool bSelected = Convert.ToBoolean(e.State & DrawItemState.Selected);
bool bValue = Convert.ToBoolean(e.State & DrawItemState.ComboBoxEdit);
rDraw = e.Bounds;
rDraw.Inflate(-1, -1);
if (bSelected & !bValue)
{
brBack = Brushes.LightBlue;
g.FillRectangle(Brushes.LightBlue, rDraw);
g.DrawRectangle(Pens.Blue, rDraw);
}
else
{
brBack = Brushes.White;
g.FillRectangle(brBack, e.Bounds);
}
try
{
//s = ((ComboBox)sender).Items[e.Index].ToString();
ComboboxColorItem oColorItem = (ComboboxColorItem)((ComboBox)sender).Items[e.Index];
s = oColorItem.ToString();
c = oColorItem.Value;
}
catch
{
s = "red";
c = Color.Red;
}
SolidBrush b = new SolidBrush(c);
Rectangle r = new Rectangle(e.Bounds.Left + 5, e.Bounds.Top + 3, 10, 10);
g.FillRectangle(b, r);
g.DrawRectangle(Pens.Black, r);
g.DrawString(s, Form.DefaultFont, Brushes.Black, e.Bounds.Left + 25, e.Bounds.Top + 1);
b.Dispose();
g.Dispose();
}
private void DataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
MessageBox.Show(e.Exception.ToString());
}
}
public class ComboboxColorItem
{
public string Name { get; }
public ushort Index { get; }
public Color Value { get; }
public ComboboxColorItem(string Name, ushort Index, Color Value)
{
this.Name = Name;
this.Index = Index;
this.Value = Value;
}
public override string ToString()
{
return Name;
}
}
}
更新:
如果我将此代码放入表单加载事件中:
this.DataGridView1.Rows.Add(new ComboboxColorItem("red", 1, Color.Red));
然后我立即得到异常
我尝试添加辅助默认构造函数,但没有任何区别:
public class ComboboxColorItem
{
public string Name { get; set; }
public ushort Index { get; set; }
public Color Value { get; set; }
public ComboboxColorItem()
{
this.Name = "red";
this.Index = 1;
this.Value = Color.Red;
}
public ComboboxColorItem(string Name, ushort Index, Color Value)
{
this.Name = Name;
this.Index = Index;
this.Value = Value;
}
public override string ToString()
{
return Name;
}
}
我也尝试将此添加到加载事件中:
cboColumn.ValueType = typeof(ComboboxColorItem);
没有影响。
更新:
我已经使用了 CellParsing 答案,我似乎不再崩溃了:
我现在唯一的评论是我希望颜色块在单元格中保持可见。但我只在单击下拉箭头时看到色块。这是一个单独的问题吗?
当你想得到字符串以外的东西时,将列的ValueType
设置为typeof(<data type>)
例如,如果它是 int
this.gridViewSettings.Columns("columnName").ValueType= typeof(Int32);
或
this.ComboboxCellcolumnName.ValueType = typeof(int);
DataGridView
在解析所选颜色项目时遇到问题。我建议您对该列应用自定义解析逻辑:
DataGridView1.CellParsing += ColorCellParsing;
private void ColorCellParsing(object sender, DataGridViewCellParsingEventArgs e)
{
var grid = (DataGridView)sender;
var column = grid.Columns[e.ColumnIndex] as DataGridViewComboBoxColumn;
if (column == null || column.Name != "Color")
return;
foreach (ComboboxColorItem item in column.Items)
{
if (item.Name == (string) e.Value)
{
e.Value = item;
e.ParsingApplied = true;
break;
}
}
}
我有这个问题。开头是这样的:
我可以双击下拉箭头并选择一种颜色确定:
此时,我可以再次点击下拉菜单,它被正确选中了:
问题是我想添加一个新行。即使我只是去点击新的行单元格:
然后我数据一个数据错误异常:
此后上一个单元格绘制不正确:
我不太明白如何解决这个问题。
我的代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using Teigha.Core;
using Teigha.TD;
namespace Viewer
{
public partial class Editor : Form
{
uint[] _CurPalette = Teigha.Core.AllPalettes.getDarkPalette();
public Editor()
{
InitializeComponent();
}
private void Editor_Load(object sender, EventArgs e)
{
DataGridViewComboBoxColumn cboColumn = new DataGridViewComboBoxColumn();
cboColumn.Name = "Color";
List<ushort> listColors = new List<ushort>();
listColors.Add(1);
listColors.Add(2);
listColors.Add(3);
listColors.Add(4);
listColors.Add(5);
listColors.Add(6);
listColors.Add(7);
listColors.Add(8);
listColors.Add(9);
listColors.Add(250);
listColors.Add(251);
listColors.Add(252);
listColors.Add(253);
listColors.Add(254);
listColors.Add(255);
foreach (ushort iColorIndex in listColors)
{
using (OdCmColor oColor = new OdCmColor())
{
oColor.setColorIndex(iColorIndex);
ComboboxColorItem oColorItem = new ComboboxColorItem(
oColor.colorNameForDisplay(),
iColorIndex,
Color.FromArgb(oColor.red(), oColor.green(), oColor.blue()));
cboColumn.Items.Add(oColorItem);
}
}
this.DataGridView1.Columns.Add(cboColumn);
}
private void DataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is ComboBox)
{
ComboBox theCB = (ComboBox)e.Control;
theCB.DrawMode = DrawMode.OwnerDrawFixed;
try
{
theCB.DrawItem -= new DrawItemEventHandler(this.combobox1_DrawItem);
}
catch { }
theCB.DrawItem += new DrawItemEventHandler(this.combobox1_DrawItem);
}
}
private void combobox1_DrawItem(object sender, DrawItemEventArgs e)
{
Graphics g = e.Graphics;
Color c = Color.Empty;
string s = "";
Brush br = SystemBrushes.WindowText;
Brush brBack;
Rectangle rDraw;
bool bSelected = Convert.ToBoolean(e.State & DrawItemState.Selected);
bool bValue = Convert.ToBoolean(e.State & DrawItemState.ComboBoxEdit);
rDraw = e.Bounds;
rDraw.Inflate(-1, -1);
if (bSelected & !bValue)
{
brBack = Brushes.LightBlue;
g.FillRectangle(Brushes.LightBlue, rDraw);
g.DrawRectangle(Pens.Blue, rDraw);
}
else
{
brBack = Brushes.White;
g.FillRectangle(brBack, e.Bounds);
}
try
{
//s = ((ComboBox)sender).Items[e.Index].ToString();
ComboboxColorItem oColorItem = (ComboboxColorItem)((ComboBox)sender).Items[e.Index];
s = oColorItem.ToString();
c = oColorItem.Value;
}
catch
{
s = "red";
c = Color.Red;
}
SolidBrush b = new SolidBrush(c);
Rectangle r = new Rectangle(e.Bounds.Left + 5, e.Bounds.Top + 3, 10, 10);
g.FillRectangle(b, r);
g.DrawRectangle(Pens.Black, r);
g.DrawString(s, Form.DefaultFont, Brushes.Black, e.Bounds.Left + 25, e.Bounds.Top + 1);
b.Dispose();
g.Dispose();
}
private void DataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
MessageBox.Show(e.Exception.ToString());
}
}
public class ComboboxColorItem
{
public string Name { get; }
public ushort Index { get; }
public Color Value { get; }
public ComboboxColorItem(string Name, ushort Index, Color Value)
{
this.Name = Name;
this.Index = Index;
this.Value = Value;
}
public override string ToString()
{
return Name;
}
}
}
更新:
如果我将此代码放入表单加载事件中:
this.DataGridView1.Rows.Add(new ComboboxColorItem("red", 1, Color.Red));
然后我立即得到异常
我尝试添加辅助默认构造函数,但没有任何区别:
public class ComboboxColorItem
{
public string Name { get; set; }
public ushort Index { get; set; }
public Color Value { get; set; }
public ComboboxColorItem()
{
this.Name = "red";
this.Index = 1;
this.Value = Color.Red;
}
public ComboboxColorItem(string Name, ushort Index, Color Value)
{
this.Name = Name;
this.Index = Index;
this.Value = Value;
}
public override string ToString()
{
return Name;
}
}
我也尝试将此添加到加载事件中:
cboColumn.ValueType = typeof(ComboboxColorItem);
没有影响。
更新:
我已经使用了 CellParsing 答案,我似乎不再崩溃了:
我现在唯一的评论是我希望颜色块在单元格中保持可见。但我只在单击下拉箭头时看到色块。这是一个单独的问题吗?
当你想得到字符串以外的东西时,将列的ValueType
设置为typeof(<data type>)
例如,如果它是 int
this.gridViewSettings.Columns("columnName").ValueType= typeof(Int32);
或
this.ComboboxCellcolumnName.ValueType = typeof(int);
DataGridView
在解析所选颜色项目时遇到问题。我建议您对该列应用自定义解析逻辑:
DataGridView1.CellParsing += ColorCellParsing;
private void ColorCellParsing(object sender, DataGridViewCellParsingEventArgs e)
{
var grid = (DataGridView)sender;
var column = grid.Columns[e.ColumnIndex] as DataGridViewComboBoxColumn;
if (column == null || column.Name != "Color")
return;
foreach (ComboboxColorItem item in column.Items)
{
if (item.Name == (string) e.Value)
{
e.Value = item;
e.ParsingApplied = true;
break;
}
}
}