因为我们可以将单个复选框添加到datagrid视图列的列,但是可以将选中的列表框添加到datagrid视图,目的是让一个单元格具有多个复选框。
我们如何添加它们?
我们如何访问其属性,例如文本和已检查?
得到了一些答案,但我无法理解 http://social.msdn.microsoft.com/Forums/en/winformsdatacontrols/thread/6c68a44c-c4ab-4caf-94e9-249ec63a90d0
答案 0 :(得分:2)
在使用此代码之前,请阅读本答案底部的评论。
<小时/> 根据问题我们如何访问此CheckListBox DataGridView Column 中的文字和复选框:
public class CheckedListBoxColumn : DataGridViewColumn
{
public CheckedListBoxColumn()
: base(new CheckedListBoxCell())
{
}
public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
if (value != null &&
!value.GetType().IsAssignableFrom(typeof(CheckedListBoxCell)))
{
throw new InvalidCastException("Must be a CheckedListBoxCell");
}
base.CellTemplate = value;
}
}
}
public class CheckedListBoxCell : DataGridViewCell
{
public CheckedListBoxCell()
: base()
{
}
public override void InitializeEditingControl(int rowIndex, object
initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
// Set the value of the editing control to the current cell value.
base.InitializeEditingControl(rowIndex, initialFormattedValue,
dataGridViewCellStyle);
CheckedListBoxEditingControl ctl =
DataGridView.EditingControl as CheckedListBoxEditingControl;
InitializeCheckedListBox(ctl, (ICollection)this.FormattedValue);
}
private void InitializeCheckedListBox(CheckedListBox ctrl, ICollection value)
{
ctrl.Items.Clear();
foreach (object obj in value)
{
ctrl.Items.Add(obj.ToString());
}
ctrl.Tag = this.Value;
}
public override Type EditType
{
get
{
return typeof(CheckedListBoxEditingControl);
}
}
protected override object GetFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle cellStyle, System.ComponentModel.TypeConverter valueTypeConverter, System.ComponentModel.TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
{
if (value == null)
{
return new List<object>();
}
return base.GetFormattedValue(value, rowIndex, ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context);
}
public override Type FormattedValueType
{
get
{
return typeof(ICollection);
}
}
public override Type ValueType
{
get
{
return typeof(ICollection);
}
}
private CheckedListBox internalControl;
protected override void Paint(System.Drawing.Graphics graphics, System.Drawing.Rectangle clipBounds, System.Drawing.Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
graphics.FillRectangle(new SolidBrush(cellStyle.BackColor), cellBounds);
if (internalControl == null)
{
internalControl = new CheckedListBox();
}
internalControl.Items.Clear();
ICollection collection = value as ICollection;
if (collection != null)
{
foreach (object obj in collection)
{
internalControl.Items.Add(obj);
}
Bitmap bmp = new Bitmap(cellBounds.Width, cellBounds.Height);
internalControl.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
graphics.DrawImage(bmp, cellBounds, new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
}
}
protected override void OnClick(DataGridViewCellEventArgs e)
{
this.DataGridView.BeginEdit(false);
base.OnClick(e);
}
}
class CheckedListBoxEditingControl : CheckedListBox, IDataGridViewEditingControl
{
DataGridView dataGridView;
private bool valueChanged = false;
int rowIndex;
public CheckedListBoxEditingControl()
{
}
// Implements the IDataGridViewEditingControl.EditingControlFormattedValue
// property.
public object EditingControlFormattedValue
{
get
{
return this.Tag;
}
set
{
// this.Tag = value;
}
}
// Implements the
// IDataGridViewEditingControl.GetEditingControlFormattedValue method.
public object GetEditingControlFormattedValue(
DataGridViewDataErrorContexts context)
{
return EditingControlFormattedValue;
}
// Implements the
// IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.
public void ApplyCellStyleToEditingControl(
DataGridViewCellStyle dataGridViewCellStyle)
{
this.Font = dataGridViewCellStyle.Font;
this.ForeColor = dataGridViewCellStyle.ForeColor;
this.BackColor = dataGridViewCellStyle.BackColor;
}
// Implements the IDataGridViewEditingControl.EditingControlRowIndex
// property.
public int EditingControlRowIndex
{
get
{
return rowIndex;
}
set
{
rowIndex = value;
}
}
// Implements the IDataGridViewEditingControl.EditingControlWantsInputKey
// method.
public bool EditingControlWantsInputKey(
Keys key, bool dataGridViewWantsInputKey)
{
// Let the DateTimePicker handle the keys listed.
switch (key & Keys.KeyCode)
{
case Keys.Left:
case Keys.Up:
case Keys.Down:
case Keys.Right:
case Keys.Home:
case Keys.End:
case Keys.PageDown:
case Keys.PageUp:
return true;
default:
return !dataGridViewWantsInputKey;
}
}
// Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit
// method.
public void PrepareEditingControlForEdit(bool selectAll)
{
// No preparation needs to be done.
}
// Implements the IDataGridViewEditingControl
// .RepositionEditingControlOnValueChange property.
public bool RepositionEditingControlOnValueChange
{
get
{
return false;
}
}
// Implements the IDataGridViewEditingControl
// .EditingControlDataGridView property.
public DataGridView EditingControlDataGridView
{
get
{
return dataGridView;
}
set
{
dataGridView = value;
}
}
// Implements the IDataGridViewEditingControl
// .EditingControlValueChanged property.
public bool EditingControlValueChanged
{
get
{
return valueChanged;
}
set
{
valueChanged = value;
}
}
// Implements the IDataGridViewEditingControl
// .EditingPanelCursor property.
public Cursor EditingPanelCursor
{
get
{
return base.Cursor;
}
}
}
一篇有趣的博客文章介绍了此课程的问题:http://dotnetgenetics.blogspot.com.au/2014/01/custom-checkedlistbox-datagridview.html
在CheckedListBoxCell类中添加一个属性以检索已检查的项目:
public ICollection CheckedItems
{
get
{
if (internalControl == null)
return null;
else
{
if (internalControl != null)
{
if (internalControl.CheckedItems.Count > 0)
{
return internalControl.CheckedItems;
}
else
{
if ((CheckedListBox)this.DataGridView.Rows[RowIndex].Cells[ColumnIndex].DataGridView.EditingControl != null)
{
CheckedListBox checks = (CheckedListBox)this.DataGridView.Rows[RowIndex].Cells[ColumnIndex].DataGridView.EditingControl;
if (checks.CheckedItems.Count > 0)
return checks.CheckedItems;
else
return null;
}
else
return null;
}
}
else
{
return null;
}
}
}
}
这是获取已检查项目的方法。
private void btnShow_Click(object sender, EventArgs e)
{
StringBuilder builder = new StringBuilder();
foreach (DataGridViewRow item in dgCheckListColumn1.Rows)
{
DataGridViewCell cell = item.Cells[1];
if (((cell as CheckedListBoxCell).CheckedItems != null))
{
if (((cell as CheckedListBoxCell).CheckedItems.Count > 0))
{
foreach (var checkItem in ((cell as CheckedListBoxCell).CheckedItems))
{
builder.AppendLine(String.Format("Row {0} : item: {1}", item.Index + 1, checkItem.ToString()));
}
builder.AppendLine(Environment.NewLine);
}
}
}
MessageBox.Show("Checked Items: \n" + builder.ToString());
}
<小时/> 我对这一切的看法是 - 它的垃圾 - 看起来像垃圾,它的行为就像垃圾......甚至感觉垃圾:
<小时/> 恕我直言,它更好地利用DataGridView的单元格点击事件并弹出一个CheckedListbox:
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 1)
{
int RowHeight1 = DataGridView1.Rows[e.RowIndex].Height;
Rectangle CellRectangle1 = DataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false);
CellRectangle1.X += DataGridView1.Left;
CellRectangle1.Y += DataGridView1.Top + RowHeight1;
Point DisplayPoint1 = PointToScreen(new Point(CellRectangle1.X, CellRectangle1.Y));
checkedListBox1.Left = CellRectangle1.X;
checkedListBox1.Top = CellRectangle1.Y;
}
}
答案 1 :(得分:0)
您可以通过创建自定义DataGridView列来完成此操作。网上有很多文章证明了这一点; here's one example。将复选框公开为属性以访问其属性。