处理自定义 DataGridView 列的大小调整事件
我尝试实现我自己的自定义 DataGridView 列。我已经使用以下代码完成了此操作。从此 MSDN 页面借用和修改: http://msdn .microsoft.com/en-us/library/system.windows.forms.idatagridvieweditingcontrol.aspx
我陷入困境的是如何通知用户控件 ucFolderBrowser gridviewcolumn 已调整大小并需要进行相应调整?
class FolderGridViewColumn : DataGridViewColumn
{
public FolderGridViewColumn() : base(new FolderCell())
{
}
public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
// Ensure that the cell used for the template is a FolderCell.
if (value != null &&
!value.GetType().IsAssignableFrom(typeof(FolderCell)))
{
throw new InvalidCastException("Must be a FolderCell");
}
base.CellTemplate = value;
}
}
}
class FolderCell : DataGridViewTextBoxCell
{
public FolderCell() : base()
{
//this.Style.Format = ""; //Can set format
}
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
FolderEditingControl ctl = DataGridView.EditingControl as FolderEditingControl;
// Use the default row value when Value property is null.
if (this.Value == null)
{
ctl.Text = (string)this.DefaultNewRowValue;
}
else
{
ctl.Text = (string)this.Value;
}
}
public override Type EditType
{
get
{
// Return the type of the editing control that FolderCell uses.
return typeof(FolderEditingControl);
}
}
public override Type ValueType
{
get
{
// Return the type of the value that FolderBrowserCell contains.
return typeof(string);
}
}
public override object DefaultNewRowValue
{
get
{
//default value.
return string.Empty;
}
}
}
class FolderEditingControl : ucFolderBrowser, IDataGridViewEditingControl
{
DataGridView dataGridView;
private bool valueChanged = false;
int rowIndex;
public FolderEditingControl() { }
// Implements the IDataGridViewEditingControl.EditingControlFormattedValue
// property.
public object EditingControlFormattedValue
{
get
{
return this.Text;
}
set
{
this.Text = (string) value;
}
}
// Implements the
// IDataGridViewEditingControl.GetEditingControlFormattedValue method.
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return this.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 textbox handle the keys listed.
switch (key & Keys.KeyCode)
{
case Keys.Left:
case Keys.Right:
case Keys.Home:
case Keys.End:
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;
}
}
protected override void OnTextChanged(EventArgs e)
{
// Notify the DataGridView that the contents of the cell
// have changed.
valueChanged = true;
this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
base.OnTextChanged(e);
}
}
public partial class ucFolderBrowser : UserControl
{
public ucFolderBrowser()
{
InitializeComponent();
}
public override string Text
{
get
{
return txtPath.Text;
}
set
{
txtPath.Text = value;
}
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.txtPath = new System.Windows.Forms.TextBox();
this.btnBrowse = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// txtPath
//
this.txtPath.Location = new System.Drawing.Point(0, 0);
this.txtPath.Name = "txtPath";
this.txtPath.Size = new System.Drawing.Size(100, 20);
this.txtPath.TabIndex = 0;
//
// btnBrowse
//
this.btnBrowse.Location = new System.Drawing.Point(100, -1);
this.btnBrowse.Name = "btnBrowse";
this.btnBrowse.Size = new System.Drawing.Size(30, 21);
this.btnBrowse.TabIndex = 1;
this.btnBrowse.Text = "...";
this.btnBrowse.UseVisualStyleBackColor = true;
this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click);
//
// ucFolderBrowser
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.btnBrowse);
this.Controls.Add(this.txtPath);
this.Name = "ucFolderBrowser";
this.Size = new System.Drawing.Size(129, 20);
this.ResumeLayout(false);
this.PerformLayout();
}
}
I have attempted to implement my own custom DataGridView column. I have done this using the following code. Borrowing and modifying from this MSDN page: http://msdn.microsoft.com/en-us/library/system.windows.forms.idatagridvieweditingcontrol.aspx
Where I am stuck is how to notify the usercontrol ucFolderBrowser that the gridviewcolumn has been resized and needs to be adjusted accordingly?
class FolderGridViewColumn : DataGridViewColumn
{
public FolderGridViewColumn() : base(new FolderCell())
{
}
public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
// Ensure that the cell used for the template is a FolderCell.
if (value != null &&
!value.GetType().IsAssignableFrom(typeof(FolderCell)))
{
throw new InvalidCastException("Must be a FolderCell");
}
base.CellTemplate = value;
}
}
}
class FolderCell : DataGridViewTextBoxCell
{
public FolderCell() : base()
{
//this.Style.Format = ""; //Can set format
}
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
FolderEditingControl ctl = DataGridView.EditingControl as FolderEditingControl;
// Use the default row value when Value property is null.
if (this.Value == null)
{
ctl.Text = (string)this.DefaultNewRowValue;
}
else
{
ctl.Text = (string)this.Value;
}
}
public override Type EditType
{
get
{
// Return the type of the editing control that FolderCell uses.
return typeof(FolderEditingControl);
}
}
public override Type ValueType
{
get
{
// Return the type of the value that FolderBrowserCell contains.
return typeof(string);
}
}
public override object DefaultNewRowValue
{
get
{
//default value.
return string.Empty;
}
}
}
class FolderEditingControl : ucFolderBrowser, IDataGridViewEditingControl
{
DataGridView dataGridView;
private bool valueChanged = false;
int rowIndex;
public FolderEditingControl() { }
// Implements the IDataGridViewEditingControl.EditingControlFormattedValue
// property.
public object EditingControlFormattedValue
{
get
{
return this.Text;
}
set
{
this.Text = (string) value;
}
}
// Implements the
// IDataGridViewEditingControl.GetEditingControlFormattedValue method.
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return this.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 textbox handle the keys listed.
switch (key & Keys.KeyCode)
{
case Keys.Left:
case Keys.Right:
case Keys.Home:
case Keys.End:
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;
}
}
protected override void OnTextChanged(EventArgs e)
{
// Notify the DataGridView that the contents of the cell
// have changed.
valueChanged = true;
this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
base.OnTextChanged(e);
}
}
public partial class ucFolderBrowser : UserControl
{
public ucFolderBrowser()
{
InitializeComponent();
}
public override string Text
{
get
{
return txtPath.Text;
}
set
{
txtPath.Text = value;
}
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.txtPath = new System.Windows.Forms.TextBox();
this.btnBrowse = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// txtPath
//
this.txtPath.Location = new System.Drawing.Point(0, 0);
this.txtPath.Name = "txtPath";
this.txtPath.Size = new System.Drawing.Size(100, 20);
this.txtPath.TabIndex = 0;
//
// btnBrowse
//
this.btnBrowse.Location = new System.Drawing.Point(100, -1);
this.btnBrowse.Name = "btnBrowse";
this.btnBrowse.Size = new System.Drawing.Size(30, 21);
this.btnBrowse.TabIndex = 1;
this.btnBrowse.Text = "...";
this.btnBrowse.UseVisualStyleBackColor = true;
this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click);
//
// ucFolderBrowser
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.btnBrowse);
this.Controls.Add(this.txtPath);
this.Name = "ucFolderBrowser";
this.Size = new System.Drawing.Size(129, 20);
this.ResumeLayout(false);
this.PerformLayout();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因此,解决方案是使用用户控件调整大小事件 - 当 DataGridView 列调整大小时,该事件会触发。
然后我意识到我什至不需要处理调整大小事件,因为无论如何我都可以停靠我的两个控件。
So turns out the solution is to use the usercontrols resize event - this event does trigger when the DataGridView column is resized.
I then realized I don't even need to handle the resize event because I can dock both my controls anyway.