class
DataGridTreeViewColumn: DataGridColumnStyle
{
private TreeView myTreeView = new TreeView ();
private DataView ChoiceDataViewSource;
private string ChoiceDisplayField;
private string ChoiceValueField;
private string ChoiceParentValueField;
private bool isEditing;
public DataGridTreeViewColumn(DataView ChoiceDataViewSource,string ChoiceDisplayField,string ChoiceValueField) : base()
{//适用于主键策略采用System.Guid 类型的表,其他类型不可能不适用,需要修改
this.ChoiceDataViewSource =ChoiceDataViewSource;
this.ChoiceDisplayField =ChoiceDisplayField;
char[] bytearray_临时=new char[] {' '};
string[] stringarrya_临时=ChoiceValueField.Split (bytearray_临时);
this.ChoiceValueField =stringarrya_临时[0];
this.ChoiceParentValueField=stringarrya_临时[1];
//myComboBox.DropDownStyle =System.Windows .Forms .ComboBoxStyle .DropDownList ;
myTreeView.Visible = false;
//myComboBox.DataSource =this.ChoiceDataViewSource;
//myComboBox.DisplayMember= this.ChoiceDisplayField;
//myComboBox.ValueMember =this.ChoiceValueField;
}
protected override void Abort(int rowNum)
{
isEditing = false;
myTreeView.AfterSelect -=new System.Windows .Forms .TreeViewEventHandler (TreeViewSelectedIndexChanged);
//myComboBox.SelectedIndexChanged -=
// new EventHandler(ComboBoxSelectedIndexChanged );
Invalidate();
}
protected override bool Commit
(CurrencyManager dataSource, int rowNum)
{
myTreeView.Bounds =Rectangle.Empty;
//myComboBox.Bounds = Rectangle.Empty;
myTreeView.AfterSelect -=new System.Windows.Forms .TreeViewEventHandler (TreeViewSelectedIndexChanged);
//myComboBox.SelectedIndexChanged -=
// new EventHandler(ComboBoxSelectedIndexChanged );
if (!isEditing)
return true;
isEditing = false;
try
{
System.Object value = myTreeView.SelectedNode.Tag ;//.SelectedValue;
SetColumnValueAtRow(dataSource, rowNum, value);
}
catch (Exception)
{
Abort(rowNum);
return false;
}
Invalidate();
return true;
}
protected override void Edit(
CurrencyManager source,
int rowNum,
Rectangle bounds,
bool readOnly,
string instantText,
bool cellIsVisible)
{ TreeView_Creator();
object value =GetColumnValueAtRow(source, rowNum);
if (cellIsVisible)
{
int h=200;
if (bounds.Height<25) h=bounds.Height *8;
if (bounds.Y >h)
{
myTreeView.Bounds = new Rectangle
(bounds.X + 2, bounds.Y+bounds.Height - 2-h,
bounds.Width - 4, h);
}
else
{
myTreeView.Bounds = new Rectangle
(bounds.X + 2, bounds.Y + 2,
bounds.Width - 4, h);
}
System.Windows .Forms .TreeNode i= FindTree (value);
if (i!=null)
{
myTreeView.SelectedNode =i;
}
myTreeView.Visible = true;
myTreeView.AfterSelect +=
new System.Windows .Forms .TreeViewEventHandler (TreeViewSelectedIndexChanged );
}
else
{
//myComboBox.Value = value;需要增加一段程序,查对对应显示项显示
myTreeView.SelectedNode =this.FindTree (value);
myTreeView.Visible = false;
}
if (myTreeView.Visible)
DataGridTableStyle.DataGrid.Invalidate(bounds);
}
private void TreeView_Creator()
{
this.myTreeView .Nodes .Clear ();
System.Windows .Forms .TreeNode snode;
string stemp=ChoiceDataViewSource.RowFilter ;
int t=ChoiceDataViewSource.Count ;//Test
ChoiceDataViewSource.RowFilter =ChoiceParentValueField+"='00000000-0000-0000-0000-000000000000'";
int int1=ChoiceDataViewSource.Count ;
string[] Displays=new string [int1];
object[] Values=new object [int1];
for (int i=0;i<int1;i++)
{
Displays[i]= ChoiceDataViewSource[i][ChoiceDisplayField].ToString ();
Values[i]=ChoiceDataViewSource[i][ChoiceValueField];
}
for (int i=0;i<int1;i++)
{
snode=new TreeNode ();
snode.Text =Displays[i];
snode.Tag =Values[i];
ChoiceDataViewSource.RowFilter =ChoiceParentValueField+"='"+Values[i].ToString ()+"'";
if (ChoiceDataViewSource.Count >0)
{
snode.Nodes .AddRange (CreatSubNodes());
}
myTreeView.Nodes .Add (snode);
}
ChoiceDataViewSource.RowFilter=stemp;
}
private System.Windows .Forms .TreeNode[] CreatSubNodes()
{
System.Windows .Forms .TreeNode[] snodes=null;
string stemp=ChoiceDataViewSource.RowFilter ;
int int1=ChoiceDataViewSource.Count ;
string[] Displays=new string [int1];
object[] Values=new object [int1];
snodes=new System.Windows .Forms .TreeNode[int1];
for (int i=0;i<int1;i++)
{
Displays[i]= ChoiceDataViewSource[i][ChoiceDisplayField].ToString ();
Values[i]=ChoiceDataViewSource[i][ChoiceValueField];
}
for (int i=0;i<int1;i++)
{
snodes[i]=new TreeNode ();
snodes[i].Text =Displays[i];
snodes[i].Tag =Values[i];
ChoiceDataViewSource.RowFilter =ChoiceParentValueField+"='"+Values[i].ToString ()+"'";
if (ChoiceDataViewSource.Count >0)
{
snodes[i].Nodes.AddRange (CreatSubNodes());
}
//myTreeView.Nodes .Add (snode);
}
//ChoiceDataViewSource.RowFilter=stemp;
return snodes;
}
protected int Find(System.Object value)
{
int int1;
int int2;
int2=ChoiceDataViewSource.Count ;
if (int2<=0)
{
return -1;
}
for (int1=0;int1<int2;int1++)
{
if (ChoiceDataViewSource[int1][ChoiceValueField ].ToString ().Trim ()==value.ToString ().Trim ())
{
return int1;
}
}
return -1;
}
private System.Windows .Forms .TreeNode FindTreeNode(System.Object value,System.Windows .Forms .TreeNode SubNode)
{
int int1;int int2;
System.Windows .Forms .TreeNode node1;
//System.Windows .Forms .TreeNode [] nodearray;
//nodearray=SubNode.Nodes ;
int2=SubNode.Nodes.Count ;
if (int2<=0)
{
return null;
}
for (int1=0;int1<int2;int1++)
{
if (SubNode.Nodes[int1].Tag .ToString ().Trim ()==value.ToString ().Trim ())
{
return SubNode.Nodes[int1];
}
if (SubNode.Nodes[int1].Nodes .Count >0)
{
node1=FindTreeNode(value,SubNode.Nodes[int1]);
if (node1!=null)
{
return node1;
}
}
}
return null;
}
protected System.Windows .Forms .TreeNode FindTree(System.Object value)
{
System.Windows .Forms .TreeNode snode;
int int1=this.myTreeView .Nodes .Count ;
for (int i=0;i<int1;i++)
{
snode=FindTreeNode(value,this.myTreeView .Nodes [i]);
if (snode!=null)
{
return snode;
}
}
return null;
}
protected override Size GetPreferredSize(
Graphics g,
object value)
{
return new Size(100, 25);//myComboBox.PreferredHeight+ 4);
}
protected override int GetMinimumHeight()
{
return 25;//this.myTreeView.hei.PreferredHeight + 4;
}
protected override int GetPreferredHeight(Graphics g,
object value)
{
return 25;//return myComboBox.PreferredHeight + 4;
}
protected override void Paint(Graphics g,
Rectangle bounds,
CurrencyManager source,
int rowNum)
{
Paint(g, bounds, source, rowNum, false);
}
protected override void Paint(
Graphics g,
Rectangle bounds,
CurrencyManager source,
int rowNum,
bool alignToRight)
{
Paint(
g,bounds,
source,
rowNum,
Brushes.Red,
Brushes.Blue,
alignToRight);
}
protected override void Paint(
Graphics g,
Rectangle bounds,
CurrencyManager source,
int rowNum,
Brush backBrush,
Brush foreBrush,
bool alignToRight)
{
object value=GetColumnValueAtRow(source, rowNum);
int int1=Find (value);
string display="";
if (int1>=0)
{
display=this.ChoiceDataViewSource [int1][ChoiceDisplayField ].ToString ();
}
Rectangle rect = bounds;
g.FillRectangle(backBrush,rect);
rect.Offset(0, 2);
rect.Height -= 2;
g.DrawString(display,
this.DataGridTableStyle.DataGrid.Font,
foreBrush, rect);
}
protected override void SetDataGridInColumn(DataGrid value)
{
base.SetDataGridInColumn(value);
if (myTreeView.Parent != null)
{
myTreeView.Parent .Controls .Remove
(myTreeView);
}
if (value != null)
{
value.Controls.Add(myTreeView);
}
}
private void TreeViewSelectedIndexChanged(object sender, System.Windows .Forms .TreeViewEventArgs e)
{
this.isEditing = true;
base.ColumnStartedEditing(myTreeView);
}
}
有些类似于DataGridComboBoxColumn,但是实现在datagrid中的树形选择。
例:学生档案 班级档案 年极档案 学校档案
则当datagrid显示学生档案时,他的学生属班级ID_Point列点击后显示“学校-年级-班级”树视,可以从中选择班级,焦点离开后显示班级名称。
还有一效率问题,因每次点击DataGridTreeViewColumn列中的单元格都根据dataview重新生成treeview,再根据当前单元格的ID_Point查找到树视中的选择项,当dataview稍大一点时,可明显感觉到延时。
暂时使用吧,以后想到更好的办法再改进。
转载于:https://www.cnblogs.com/yitian/archive/2008/09/12/1290001.html