我有一个位于here的示例项目。
项目有一个主窗体Form1
,用户可以在datagridview中输入客户。 CustomerType
列是自定义控件,当用户点击该按钮时,会弹出一个搜索表单Form2
。
搜索表单填充了CustomerType
类型的列表。用户可以通过双击该行来选择记录,并且应该在自定义控件中设置此对象。然后DataGridView
应显示Description
属性,但在后台,每个单元格应保存该值(即CustomerType
实例)。
相关代码位于以下类别中:
列类:
public class DataGridViewCustomerTypeColumn : DataGridViewColumn
{
public DataGridViewCustomerTypeColumn()
: base(new CustomerTypeCell())
{ }
public override DataGridViewCell CellTemplate
{
get { return base.CellTemplate; }
set
{
if (value != null && !value.GetType().IsAssignableFrom(typeof(CustomerTypeCell)))
{
throw new InvalidCastException("Should be CustomerTypeCell.");
}
base.CellTemplate = value;
}
}
}
细胞类:
public class CustomerTypeCell : DataGridViewTextBoxCell
{
public CustomerTypeCell()
: base()
{ }
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
CustomerTypeSearch ctl = DataGridView.EditingControl as CustomerTypeSearch;
if (this.Value == null)
ctl.Value = (CustomerType)this.DefaultNewRowValue;
else
ctl.Value = (CustomerType)this.Value;
}
public override Type EditType
{
get { return typeof(CustomerTypeSearch); }
}
public override Type ValueType
{
get { return typeof(CustomerType); }
}
public override object DefaultNewRowValue
{
get { return null; }
}
}
自定义控件:
public partial class CustomerTypeSearch : UserControl, IDataGridViewEditingControl
{
private DataGridView dataGridView;
private int rowIndex;
private bool valueChanged = false;
private CustomerType value;
public CustomerTypeSearch()
{
InitializeComponent();
}
public CustomerType Value
{
get { return this.value; }
set
{
this.value = value;
if (value != null)
textBoxSearch.Text = value.Description;
else
textBoxSearch.Clear();
}
}
private void buttonSearch_Click(object sender, EventArgs e)
{
Form2 f = new Form2();
DialogResult dr = f.ShowDialog(this);
if (dr == DialogResult.OK)
{
Value = f.SelectedValue;
}
}
#region IDataGridViewEditingControl implementation
public object EditingControlFormattedValue
{
get
{
if (this.value != null)
return this.value.Description;
else
return null;
}
set
{
if (this.value != null)
this.value.Description = (string)value;
}
}
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return EditingControlFormattedValue;
}
public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
this.BorderStyle = BorderStyle.None;
this.Font = dataGridViewCellStyle.Font;
}
public int EditingControlRowIndex
{
get { return rowIndex; }
set { rowIndex = value; }
}
public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey)
{
return false;
}
public void PrepareEditingControlForEdit(bool selectAll)
{
//No preparation needs to be done
}
public bool RepositionEditingControlOnValueChange
{
get { return false; }
}
public DataGridView EditingControlDataGridView
{
get { return dataGridView; }
set { dataGridView = value; }
}
public bool EditingControlValueChanged
{
get { return valueChanged; }
set { valueChanged = value; }
}
public Cursor EditingPanelCursor
{
get { return base.Cursor; }
}
#endregion
private void CustomerTypeSearch_Resize(object sender, EventArgs e)
{
buttonSearch.Left = this.Width - buttonSearch.Width;
textBoxSearch.Width = buttonSearch.Left;
}
}
但是,DataGridView
没有显示文字,也没有保留每个单元格的CustomerType
值。
我错过了什么?
答案 0 :(得分:0)
首先,将ToString()
方法覆盖到CustomerType
类。
其次,为避免解析错误,请在CustomerTypeSearch
类中修改以下方法:
public CustomerType Value
{
get { return this.value; }
set
{
this.value = value;
if (value != null)
textBoxSearch.Text = value.Description;
else
textBoxSearch.Clear();
valueChanged = true;
if ((EditingControlDataGridView.CurrentCell as CustomerTypeCell) != null)
(EditingControlDataGridView.CurrentCell as CustomerTypeCell).Value = value;
}
}
然后,将此函数添加到CustormerTypeCell
类:
protected override bool SetValue(int rowIndex, object value)
{
if (value != null)
return base.SetValue(rowIndex, value);
return false;
}
最后,添加它来处理数据错误:
private void dataGridView_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
e.Cancel = false;
}