Winform下的Datagrid的列风格(5)—DataGridTreeViewColumn

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(10025);//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(
02);
            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稍大一点时,可明显感觉到延时。
暂时使用吧,以后想到更好的办法再改进。
posted on 2005-04-02 15:08  爱好  阅读(1195)  评论(1编辑  收藏  举报