c# - Winform DatagridView上显示下拉树

Winform的DatagridView是不支持下拉树的,所以需要扩展

废话不多说,直接贴代码

首先需要对comBox扩展,下拉内容变成TreeView

using System.Drawing;
using System.Windows.Forms;
namespace WindowsApplication23
{
public class ComboBoxTreeView : ComboBox
{
private const int WM_LBUTTONDOWN = 0x201, WM_LBUTTONDBLCLK = 0x203;
ToolStripControlHost treeViewHost;
ToolStripDropDown dropDown;
public ComboBoxTreeView()
{
TreeView treeView = new TreeView();
treeView.AfterSelect += new TreeViewEventHandler(treeView_AfterSelect);
treeView.BorderStyle = BorderStyle.None;

treeViewHost = new ToolStripControlHost(treeView);
dropDown = new ToolStripDropDown();
dropDown.Width = this.Width;
dropDown.Items.Add(treeViewHost);
}
public void treeView_AfterSelect(object sender, TreeViewEventArgs e)
{
this.Text = TreeView.SelectedNode.Text;
dropDown.Close();
}
public TreeView TreeView
{
get { return treeViewHost.Control as TreeView; }
}
private void ShowDropDown()
{
if (dropDown != null)
{
treeViewHost.Size = new Size(DropDownWidth - 2, DropDownHeight);
dropDown.Show(this, 0, this.Height);
}
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_LBUTTONDBLCLK || m.Msg == WM_LBUTTONDOWN)
{
ShowDropDown();
return;
}
base.WndProc(ref m);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (dropDown != null)
{
dropDown.Dispose();
dropDown = null;
}
}
base.Dispose(disposing);
}
}

}
然后需要扩展DataGridViewTextBoxCell为DataGridViewTreeViewCell
using System;
using System.Windows.Forms;

namespace WindowsApplication23
{
public class DataGridViewTreeViewCell:DataGridViewTextBoxCell
{
public DataGridViewTreeViewCell()
{

}
public override void InitializeEditingControl(int rowIndex, object
initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue,
dataGridViewCellStyle);
DataGridViewTreeViewEditingControl ctl =
DataGridView.EditingControl as DataGridViewTreeViewEditingControl;
ctl.Text = (string)this.Value;
}

public override Type EditType
{
get
{
return typeof(DataGridViewTreeViewEditingControl);
}
}

public override Type ValueType
{
get
{
return typeof(string);
}
}

public override object DefaultNewRowValue
{
get
{
return "";
}
}
}
}
接着扩展DataGridViewColumn 支持DataGridViewTreeViewColumn 下拉树类型
using System;
using System.Windows.Forms;

namespace WindowsApplication23
{
public class DataGridViewTreeViewColumn:DataGridViewColumn
{
public DataGridViewTreeViewColumn():
base(new DataGridViewTreeViewCell())
{

}
public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
if (value != null && !value.GetType().IsAssignableFrom(typeof(DataGridViewTreeViewCell)))
{
throw new InvalidCastException("不是DataGridViewTreeViewCell");
}
base.CellTemplate = value;
}
}
}
}

最后形成一个新的空间,一个DataGridViewEditingControl
using System.Windows.Forms;

namespace WindowsApplication23
{
public class DataGridViewTreeViewEditingControl:ComboBoxTreeView,IDataGridViewEditingControl
{
protected int rowIndex;
protected DataGridView dataGridView;
protected bool valueChanged = false;

public DataGridViewTreeViewEditingControl()
{

}
//重写基类
protected override void OnTextChanged(System.EventArgs e)
{
base.OnTextChanged(e);
NotifyDataGridViewOfValueChange();
}
// 当text值发生变化时,通知DataGridView
private void NotifyDataGridViewOfValueChange()
{
valueChanged = true;
dataGridView.NotifyCurrentCellDirty(true);
}
/// <summary>
/// 在Cell被编辑的时候光标显示
/// </summary>
public Cursor EditingPanelCursor
{
get
{
return Cursors.IBeam;
}
}
/// <summary>
/// 获取或设置所在的DataGridView
/// </summary>
public DataGridView EditingControlDataGridView
{
get
{
return dataGridView;
}

set
{
dataGridView = value;
}
}

/// <summary>
/// 获取或设置格式化后的值
/// </summary>
public object EditingControlFormattedValue
{
set
{
Text = value.ToString();
NotifyDataGridViewOfValueChange();
}
get
{
return this.Text;
}

}
/// <summary>
/// 获取控件的Text值
/// </summary>
/// <param name="context">错误上下文</param>
/// <returns></returns>
public virtual object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return Text;
}

/// <summary>
/// 编辑键盘
/// </summary>
/// <param name="keyData"></param>
/// <param name="dataGridViewWantsInputKey"></param>
/// <returns></returns>
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 false;
}
}

public void PrepareEditingControlForEdit(bool selectAll)
{
}
public virtual bool RepositionEditingControlOnValueChange
{
get
{
return false;
}
}
/// <summary>
/// 控件所在行
/// </summary>
public int EditingControlRowIndex
{
get
{
return this.rowIndex;
}

set
{
this.rowIndex = value;
}
}
/// <summary>
/// 设置样式
/// </summary>
/// <param name="dataGridViewCellStyle"></param>
public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
this.Font = dataGridViewCellStyle.Font;
this.ForeColor = dataGridViewCellStyle.ForeColor;
this.BackColor = dataGridViewCellStyle.BackColor;
}
/// <summary>
/// 是否值发生了变化
/// </summary>
public bool EditingControlValueChanged
{
get
{
return valueChanged;
}

set
{
this.valueChanged = value;
}
}
}
}

以上四步就得到了扩展的基础类,要想使用,必须引用这些类,这样在DataGridView的属性栏的columnType中就会将扩展的DataGridViewTreeViewColumn类型包含进来。
然后在对DataGridView的初始化操作,就可以添加该类型了

接下来是测试一下

需要初始化

private void dgrdViewDataType_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
var dgvTree = e.Control as DataGridViewTreeViewEditingControl;
if (dgvTree != null)
{
var root = new TreeNode("评价", 0, 0);
root.Nodes.Add("烃源岩有机岩相带评价图");
root.Nodes.Add("有利储存段评价表");
root.Nodes.Add("储层综合评价图");
root.Nodes.Add("盖层评价图");
dgvTree.TreeView.Nodes.Clear();
dgvTree.TreeView.Nodes.Add(root);
dgvTree.TreeView.ExpandAll();
}
}

这样每次点击下拉的时候,就会读取数据赋值,并显示下拉树。

以上就达到了,在DataGridView中显示下拉树的效果,但是还需要能对下拉树查询,这个还有待扩展!
————————————————
版权声明:本文为CSDN博主「GRACE_ETERNITY」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Shiyaru1314/article/details/51920494

原文地址:https://www.cnblogs.com/ljs-13/p/12108657.html

时间: 2024-08-27 16:03:38

c# - Winform DatagridView上显示下拉树的相关文章

navLI鼠标滑上显示下拉导航

<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>li导航</title> <style type="text/css"> *{padding: 0;margin: 0;} #box{width: 100%;background: red;height: 50px;margin: 0 auto;position: r

EXTJS下拉树ComboBoxTree参数提交及回显方法

http://blog.csdn.net/wjlht/article/details/6085245 使用extjs可以构造出下拉数,但是不方便向form提交参数,在此,笔者想到一个办法,很方便ComboBoxTree向form提交. 原理: 在form中增加一个隐藏的字段,当在comboBoxTree中选定值后自动在隐藏字段中赋值. 为实现此方法,需要重载comboBoxTree中collapse事件方法. Ext.ux.ComboBoxTree = function(){    this.t

Extjs下拉树代码测试总结

http://blog.csdn.net/kunoy/article/details/8067801 首先主要代码源自网络,对那些无私的奉献者表示感谢! 笔者对这些代码做了二次修改,并总结如下: Extjs3.x版本下拉树代码: [javascript] view plaincopy Ext.ux.TreeCombo = Ext.extend(Ext.form.ComboBox, { constructor : function(cfg) { cfg = cfg || {}; Ext.ux.Tr

Android PullToRefresh上、下拉刷新

支持各种上.下拉刷新. Github: https://github.com/chrisbanes/Android-PullToRefresh Features Supports both Pulling Down from the top, and Pulling Up from the bottom (or even both). Animated Scrolling for all devices. Over Scroll supports for devices on Android v

WPF 组织机构下拉树多选,递归绑定方式现实

原文:WPF 组织机构下拉树多选,递归绑定方式现实 使用HierarchicalDataTemplate递归绑定现实 XAML代码: <UserControl x:Class="SunCreate.CombatPlatform.Client.MultiSelOrgTree" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas

bootstrap怎么设置下拉菜单不点击,改成鼠标悬停直接显示下拉菜单

方法一: 实际上比较简单,只需要加一个css设置下hover的状态,把下拉菜单设置成block,具体css:.nav > li:hover .dropdown-menu {display: block;} 但是主导航失去链接的效果! 方法二: 不仅可以解决Bootstrap鼠标悬停的问题,还可以让一个菜单恢复链接实现点击下拉菜单效果是JS实现的,分析bootstrap.js文件发现,Bootstrap把下拉菜单写成了一个JQuery插件,在dropdown代码段中找到了关键的几句:$(docum

ComboBox连接数据库、显示下拉框选项

?本文从http://blog.csdn.net/susidian/article/details/7027007处学习得来. ?如何将combobox控件绑定数据库,并在下拉框中显示从数据库中查找得到的数据.如何在上一个combobox框中筛选下一个combobox中可以选择的的选项. 贴出代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usi

上、下拉电阻

单片机上拉电阻作用 加上拉电阻或下拉电阻就是从电源V+或V-端到集成电路器件输出端加装一个电阻,即直接在器件的输出脚到电源V+或V-端焊接一个电阻即可.1.上拉电阻对器件注入电流,常见的加装目的有两个:(1)提高输出电平.如TTL输出驱动COM的电平匹配,这是非常必要的.(2)加大输出驱动能力,但对于非OC或OD输出型电路其作用是有限的,如果用于驱动类似LED不加上拉或下拉电阻也是可以的,应该从负载限流电阻等方面考虑解决,如果负载比较重,应该加装输出缓冲或功率驱动电路.对于OC或OD电路,必须由

jquery的隐藏和显示——下拉框式

下拉框定义value值 后面写上onchange方法(onchange 事件会在域的内容改变时发生) 然后定义方法, 然后两个span解决.