C# Windows窗体DataGridView单元格中的主机树视图
我想为DataGridView创建一个TreeView列。我按照中的示例扩展了TreeView,如下所示C# Windows窗体DataGridView单元格中的主机树视图,c#,.net,winforms,datagridview,C#,.net,Winforms,Datagridview,我想为DataGridView创建一个TreeView列。我按照中的示例扩展了TreeView,如下所示 public class TreeViewEditingControl : TreeView, IDataGridViewEditingControl public class TreeViewCell : DataGridViewComboBoxCell // Not sure whether this should be DataGridViewTextBoxCell 这是我的问题。
public class TreeViewEditingControl : TreeView, IDataGridViewEditingControl
public class TreeViewCell : DataGridViewComboBoxCell // Not sure whether this should be DataGridViewTextBoxCell
这是我的问题。我可以在单元格中看到树状视图,但我不知道当用户单击单元格时(当组合框展开时),如何增加单元格/树状视图的高度。有人对此有什么想法吗?我会生成一个新的无边界表单,里面停靠一个TreeCtrl,我用CalendarControl完成了这项工作,效果很好。如果将表单的左上角设置为正在编辑的单元格的左上角,用户将不知道差异。希望这就是你要找的 编辑: 下面是我为文件选择单元所做的一个实现。它有一个浏览按钮,当您单击该按钮进行编辑时,它会显示在单元格中,并打开一个FileOpenDialog。代码很长,但我认为您可以选择需要实现的部分
public class DataGridViewFileColumn : DataGridViewColumn
{
public DataGridViewFileColumn() : base(new DataGridViewFileCell())
{
BrowseLabel = "...";
SaveFullPath = false;
}
public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
// Ensure that the cell used for the template is a DataGridViewFileCell.
if (value != null &&
!value.GetType().IsAssignableFrom(typeof(DataGridViewFileCell)))
{
throw new InvalidCastException("Must be a DataGridViewFileCell");
}
base.CellTemplate = value;
}
}
[Description("Label to place on Browse button"),Category("Appearance")]
[DefaultValue("...")]
public string BrowseLabel
{
get;
set;
}
[Description("Save full path name"), Category("Behavior")]
[DefaultValue(true)]
public bool SaveFullPath
{
get;
set;
}
}
public class DataGridViewFileCell : DataGridViewTextBoxCell
{
public DataGridViewFileCell() : 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);
FileEditingControl ctl = (FileEditingControl)DataGridView.EditingControl;
// Use the default row value when Value property is null.
if (this.Value == null)
{
ctl.Filename = this.DefaultNewRowValue.ToString();
}
else
{
ctl.Filename = this.Value.ToString();
}
}
public override Type EditType
{
get
{
// Return the type of the editing control that DataGridViewFileCell uses.
return typeof(FileEditingControl);
}
}
public override Type ValueType
{
get
{
// Return the type of the value that DataGridViewFileCell contains.
return typeof(string);
}
}
}
class FileEditingControl : FileTextBox, IDataGridViewEditingControl
{
DataGridView dataGridView;
private bool valueChanged = false;
int rowIndex;
public FileEditingControl()
{
}
#region IDataGridViewEditingControl implementations
public object EditingControlFormattedValue
{
get
{
return Filename;
}
set
{
if (value is String)
{
try
{
Filename = (String)value;
}
catch
{
Filename = value.ToString();
}
}
}
}
public object GetEditingControlFormattedValue(
DataGridViewDataErrorContexts context)
{
return EditingControlFormattedValue;
}
public void ApplyCellStyleToEditingControl(
DataGridViewCellStyle dataGridViewCellStyle)
{
this.Font = dataGridViewCellStyle.Font;
}
public int EditingControlRowIndex
{
get
{
return rowIndex;
}
set
{
rowIndex = value;
}
}
public bool EditingControlWantsInputKey(
Keys key, bool dataGridViewWantsInputKey)
{
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;
}
}
public void PrepareEditingControlForEdit(bool selectAll)
{
}
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
protected override void OnValueChanged(FileEventArgs eventargs)
{
// Notify the DataGridView that the contents of the cell
// have changed.
valueChanged = true;
this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
base.OnValueChanged(eventargs);
}
}
public partial class FileTextBox : UserControl
{
#region Constructors
public FileTextBox()
{
InitializeComponent();
Tooltip = new ToolTip();
SaveFullPath = false;
AllowMultipleFiles = false;
BrowseLabel = "...";
}
#endregion Constructors
#region Properties
/// <summary>
/// Tooltip object used to show full path name
/// </summary>
private ToolTip Tooltip;
/// <summary>
/// Return the full path or just the filename?
/// </summary>
[Description("Save Full Path"), Category("Behavior")]
[DefaultValue(false)]
public bool SaveFullPath
{
get;
set;
}
/// <summary>
/// String representing the filename for this control
/// </summary>
public override string Text
{
get
{
return base.Text;
}
set
{
if (base.Text != value)
{
base.Text = value;
Tooltip.SetToolTip(this, base.Text);
Invalidate();
OnValueChanged(new FileEventArgs(base.Text));
}
}
}
[Description("Browse Label"), Category("Appearance")]
[DefaultValue("...")]
public string BrowseLabel
{
get
{
return Browse.Text;
}
set
{
Browse.Text = value;
Browse.Width = TextRenderer.MeasureText(Browse.Text, Browse.Font).Width + 8;
Browse.Location = new Point(this.Width - Browse.Width, Browse.Location.Y);
}
}
[Description("Allow Multiple Files"), Category("Behavior")]
[DefaultValue(false)]
public bool AllowMultipleFiles
{
get;
set;
}
/// <summary>
/// Selected filename (same as Text property)
/// </summary>
[Description("Filename"), Category("Data")]
public string Filename
{
get { return Text; }
set { Text = value; }
}
#endregion Properties
#region Event Handlers
/// <summary>
/// Event raised when
/// </summary>
public event EventHandler ValueChanged;
protected virtual void OnValueChanged(FileEventArgs eventargs)
{
eventargs.Filename = Filename;
if (this.ValueChanged != null)
this.ValueChanged(this, eventargs);
}
private void Browse_Click(object sender, EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.FileName = Text;
dlg.Multiselect = AllowMultipleFiles;
if (dlg.ShowDialog() == DialogResult.OK)
{
if (SaveFullPath)
Text = dlg.FileName;
else
Text = dlg.SafeFileName;
}
}
protected override void OnPaint(PaintEventArgs e)
{
// Draw the client window
Rectangle r = new Rectangle(new Point(0, 0), new Size(Size.Width-1, Size.Height-1));
Graphics g = e.Graphics;
g.FillRectangle(new SolidBrush(SystemColors.Window), r);
g.DrawRectangle(new Pen(VisualStyleInformation.TextControlBorder), r);
r.Y += Margin.Top;
r.Width -= Browse.Width;
// Fill with Text
TextRenderer.DrawText(g, Text, Font, r, ForeColor, TextFormatFlags.PathEllipsis);
base.OnPaint(e);
}
private void FileTextBox_DragDrop(object sender, DragEventArgs e)
{
DataObject data = (DataObject)e.Data;
StringCollection filenames = data.GetFileDropList();
if ( filenames.Count == 1)
Text = filenames[0];
}
private void FileTextBox_DragEnter(object sender, DragEventArgs e)
{
DataObject data = (DataObject)e.Data;
StringCollection filenames = data.GetFileDropList();
if (/*!AllowMultipleFiles &&*/ filenames.Count == 1)
e.Effect = DragDropEffects.Link;
}
#endregion Event Handlers
}
public class FileEventArgs : EventArgs
{
public FileEventArgs(string Text)
{
Filename = Text;
}
/// <summary>
/// Name of the file in the control
/// </summary>
public String Filename { get; set; }
}
公共类DataGridViewFileColumn:DataGridViewColumn
{
公共DataGridViewFileColumn():基(新DataGridViewFileCell())
{
BrowseLabel=“…”;
SaveFullPath=false;
}
公共覆盖DataGridViewCell单元模板
{
得到
{
返回base.CellTemplate;
}
设置
{
//确保用于模板的单元格是DataGridViewFileCell。
if(值!=null&&
!value.GetType().IsAssignableFrom(typeof(DataGridViewFileCell)))
{
抛出新的InvalidCastException(“必须是DataGridViewFileCell”);
}
base.CellTemplate=值;
}
}
[说明(“放置在浏览按钮上的标签”)、类别(“外观”)]
[默认值(“…”)]
公共字符串BrowseLabel
{
得到;
设置
}
[说明(“保存完整路径名”)、类别(“行为”)]
[默认值(真)]
公共bool SaveFullPath
{
得到;
设置
}
}
公共类DataGridViewFileCell:DataGridViewTextBoxCell
{
公共DataGridViewFileCell():base()
{
}
public override void initializeditingcontrol(int行索引,对象
initialFormattedValue,DataGridViewCellStyle DataGridViewCellStyle)
{
//将编辑控件的值设置为当前单元格值。
base.InitializeEditingControl(行索引、InitializeFormattedValue、,
dataGridViewCellStyle);
FileEditingControl ctl=(FileEditingControl)DataGridView.EditingControl;
//值属性为空时使用默认行值。
if(this.Value==null)
{
ctl.Filename=this.DefaultNewRowValue.ToString();
}
其他的
{
ctl.Filename=this.Value.ToString();
}
}
公共覆盖类型EditType
{
得到
{
//返回DataGridViewFileCell使用的编辑控件的类型。
返回类型(FileEditingControl);
}
}
公共重写类型ValueType
{
得到
{
//返回DataGridViewFileCell包含的值的类型。
返回类型(字符串);
}
}
}
类FileEditingControl:FileTextBox,IDataGridViewEditingControl
{
DataGridView DataGridView;
私有布尔值更改=false;
整数行索引;
公共文件编辑控件()
{
}
#区域IDataGridViewEditingControl实现
公共对象EditingControlFormattedValue
{
得到
{
返回文件名;
}
设置
{
if(值为字符串)
{
尝试
{
文件名=(字符串)值;
}
抓住
{
Filename=value.ToString();
}
}
}
}
公共对象GetEditingControlFormattedValue(
DataGridViewDataErrorContext(上下文)
{
返回EditingControlFormattedValue;
}
public void applycellstyletoediting控件(
DataGridViewCellStyle(DataGridViewCellStyle)
{
this.Font=dataGridViewCellStyle.Font;
}
公共整数编辑控制行索引
{
得到
{
返回行索引;
}
设置
{
行索引=值;
}
}
public bool EditingControlWantInputKey(
Keys键,布尔数据网格视图WANTINSPUTTKEY)
{
开关(钥匙和钥匙。钥匙代码)
{
箱子钥匙。左:
案例密钥。向上:
案例键。向下:
箱子钥匙。右:
案例密钥。主页:
案例关键。结束:
case Keys.PageDown:
case Keys.PageUp:
返回true;
违约:
return!DataGridViewWantInputKey;
}
}
public void PrepareEditingControlForEdit(bool selectAll)
{
}
公共布尔重新定位编辑控制值更改
{
得到
{
返回false;
}
}
公共DataGridView编辑控制DataGridView
{
得到
{
返回dataGridView;
}
设置
{
dataGridView=值;
}
}
公共布尔编辑控制值已更改
{
得到
{
返回值已更改;
}
设置
{
valueChanged=值;
}
}
公共游标编辑面板游标
{
得到
{
返回base.Cursor;
}
}
#端区
受保护的覆盖无效OnValueChanged(FileEventArgs eventargs)
{
//通知DataGridView单元格的内容
//已经改变了。
valueChanged=true;
this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
base.OnValueChanged(事件参数);
}
}
公共部分类FileTextBox:UserControl
{
#瑞吉