好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

C#自定义DataGridViewColumn显示TreeView

我们可以自定义datagridview的datagridviewcolumn来实现自定义的列,下面介绍一下如何通过扩展datagridviewcolumn来实现一个treeviewcolumn

1.treeviewcolumn类

 treeviewcolumn继承自datagridviewcolumn,为了动态给treeviewcolumn传入一个treeview,这里暴露出一个公共属性_root,可以绑定一个初始化的treeview. 另外需要重写datagridcell类型的celltemplate,这里返还一个treeviewcell(需要自定义) 

?

/// <summary>

  /// host treeview in datagridview cell

  /// </summary>

  public class treeviewcolumn : datagridviewcolumn

  {

   public treeviewcolumn()

    : base ( new treeviewcell())

   {

   }

   [description( "set treeview root in datagridview cell" ), category( "treeview" )]

   public treeview _root

   {

    get { return roots.tree;}

    set {roots.tree=value;}

   }

   public override datagridviewcell celltemplate

   {

    get

    {

     return base .celltemplate;

    }

    set

    {

     // ensure that the cell used for the template is a treeviewcell.

     if (value != null &&

      !value.gettype().isassignablefrom( typeof (treeviewcell)))

     {

      throw new invalidcastexception( "must be a treeviewcell" );

     }

     base .celltemplate = value;

    }

   }

  }

2.treeviewcell类

    上面treeviewcolumn重写了celltemplate,返回的就是自定义的treeviewcell,这里就是具体实现其逻辑。一般来说选择树控件的节点后,返回的是一个文本信息,是文本类型,可以继承datagridviewtextboxcell,并重写initializeeditingcontrol来进行自定义的datagridview.editingcontrol (编辑控件)。

?

public class treeviewcell : datagridviewtextboxcell

  {

   public treeviewcell()

    : 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);

    treevieweditingcontrol ctl =

     datagridview.editingcontrol as treevieweditingcontrol;

    // use the default row value when value property is null.

    if ( this .value == null )

    {

     ctl.selectednode = new treenode( this .defaultnewrowvalue.tostring());

    }

    else

    {

     ctl.selectednode = new treenode( this .value.tostring());

    }

   }

   public override type edittype

   {

    get

    {

     // return the type of the editing control that calendarcell uses.

     return typeof (treevieweditingcontrol);

    }

   }

   public override type valuetype

   {

    get

    {

     // return the type of the value that calendarcell contains.

     return typeof ( string );

    }

   }

   public override object defaultnewrowvalue

   {

    get

    {

     // use the current date and time as the default value.

     return "" ;

    }

   }

  }

3.treevieweditingcontrol类

  treevieweditingcontrol为编辑控件,当用户编辑treeviewcell时,显示的为树编辑控件,需要继承treeview,同时实现idatagridvieweditingcontrol接口,实现以下方法:

?

public class treevieweditingcontrol : treeview, idatagridvieweditingcontrol

  {

   datagridview datagridview;

   private bool valuechanged = false ;

   int rowindex;

   public treevieweditingcontrol()

   {

    try

    {

     //必须加roots.tree.nodes[].clone() 否则报错 不能在多处增添或插入项,必须首先将其从当前位置移除或将其克隆

     this .nodes.add(roots.tree.nodes[].clone() as treenode);

     this .selectednode = this .nodes[];

    }

    catch (exception ex)

    {

     messagebox.show(ex.message);

    }

   }

   // implements the idatagridvieweditingcontrol.editingcontrolformattedvalue

   // property.

   public object editingcontrolformattedvalue

   {

    get

    {

     return this .selectednode.text;

    }

    set

    {

     if (value is string )

     {

      try

      {

       // this will throw an exception of the string is

       // null, empty, or not in the format of a date.

       this .selectednode = new treenode(( string )value);

      }

      catch

      {

       // in the case of an exception, just use the

       // default value so we're not left with a null

       // value.

       this .selectednode = new treenode( "" );

      }

     }

    }

   }

   // implements the

   // idatagridvieweditingcontrol.geteditingcontrolformattedvalue method.

   public object geteditingcontrolformattedvalue(

    datagridviewdataerrorcontexts context)

   {

    return 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 treeviewpicker 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 !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 onafterexpand(treevieweventargs e)

   {

    base .onafterexpand(e);

    this .datagridview.columns[ this .datagridview.currentcell.columnindex].width = this .width+;

    this .datagridview.rows[ this .datagridview.currentcell.rowindex].height = this .height+;

   }

   protected override void onafterselect(treevieweventargs e)

   {

    // notify the datagridview that the contents of the cell

    // have changed.

    valuechanged = true ;

    this .editingcontroldatagridview.notifycurrentcelldirty( true );

    base .onafterselect(e);

   }

  }

  为了在不同类之间传递参数,定义一个全局静态类:

?

/// <summary>

  /// 静态类的静态属性,用于在不同class间传递参数

  /// </summary>

  public static class roots

  {

   //从前台绑定树

  public static treeview tree = null ;

  }

完整代码为:

?

using system;

using system.collections.generic;

using system.linq;

using system.text;

using system.windows.forms;

using system.componentmodel;

namespace host_controls_in_windows_forms_datagridview_cells

{

  /// <summary>

  /// 静态类的静态属性,用于在不同class间传递参数

  /// </summary>

  public static class roots

  {

   //从前台绑定树

   public static treeview tree = null ;

  }

  /// <summary>

  /// host treeview in datagridview cell

  /// </summary>

  public class treeviewcolumn : datagridviewcolumn

  {

   public treeviewcolumn()

    : base ( new treeviewcell())

   {

   }

   [description( "set treeview root in datagridview cell" ), category( "treeview" )]

   public treeview _root

   {

    get { return roots.tree;}

    set {roots.tree=value;}

   }

   public override datagridviewcell celltemplate

   {

    get

    {

     return base .celltemplate;

    }

    set

    {

     // ensure that the cell used for the template is a treeviewcell.

     if (value != null &&

      !value.gettype().isassignablefrom( typeof (treeviewcell)))

     {

      throw new invalidcastexception( "must be a treeviewcell" );

     }

     base .celltemplate = value;

    }

   }

  }

  //----------------------------------------------------------------------

  public class treeviewcell : datagridviewtextboxcell

  {

   public treeviewcell()

    : 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);

    treevieweditingcontrol ctl =

     datagridview.editingcontrol as treevieweditingcontrol;

    // use the default row value when value property is null.

    if ( this .value == null )

    {

     ctl.selectednode = new treenode( this .defaultnewrowvalue.tostring());

    }

    else

    {

     ctl.selectednode = new treenode( this .value.tostring());

    }

   }

   public override type edittype

   {

    get

    {

     // return the type of the editing control that calendarcell uses.

     return typeof (treevieweditingcontrol);

    }

   }

   public override type valuetype

   {

    get

    {

     // return the type of the value that calendarcell contains.

     return typeof ( string );

    }

   }

   public override object defaultnewrowvalue

   {

    get

    {

     // use the current date and time as the default value.

     return "" ;

    }

   }

  }

  //-----------------------------------------------------------------

public class treevieweditingcontrol : treeview, idatagridvieweditingcontrol

  {

   datagridview datagridview;

   private bool valuechanged = false ;

   int rowindex;

   public treevieweditingcontrol()

   {

    try

    {

     //必须加roots.tree.nodes[].clone() 否则报错 不能在多处增添或插入项,必须首先将其从当前位置移除或将其克隆

     this .nodes.add(roots.tree.nodes[].clone() as treenode);

     this .selectednode = this .nodes[];

    }

    catch (exception ex)

    {

     messagebox.show(ex.message);

    }

   }

   // implements the idatagridvieweditingcontrol.editingcontrolformattedvalue

   // property.

   public object editingcontrolformattedvalue

   {

    get

    {

     return this .selectednode.text;

    }

    set

    {

     if (value is string )

     {

      try

      {

       // this will throw an exception of the string is

       // null, empty, or not in the format of a date.

       this .selectednode = new treenode(( string )value);

      }

      catch

      {

       // in the case of an exception, just use the

       // default value so we're not left with a null

       // value.

       this .selectednode = new treenode( "" );

      }

     }

    }

   }

   // implements the

   // idatagridvieweditingcontrol.geteditingcontrolformattedvalue method.

   public object geteditingcontrolformattedvalue(

    datagridviewdataerrorcontexts context)

   {

    return 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 treeviewpicker 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 !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 onafterexpand(treevieweventargs e)

   {

    base .onafterexpand(e);

    this .datagridview.columns[ this .datagridview.currentcell.columnindex].width = this .width+;

    this .datagridview.rows[ this .datagridview.currentcell.rowindex].height = this .height+;

   }

   protected override void onafterselect(treevieweventargs e)

   {

    // notify the datagridview that the contents of the cell

    // have changed.

    valuechanged = true ;

    this .editingcontroldatagridview.notifycurrentcelldirty( true );

    base .onafterselect(e);

   }

  }

}

  当编辑无误后,可以在添加列的时候看到treeviewcolumn类型。此类型暴露出一个_root属性,可以绑定外部的一个带数据的treeview。

  运行代码,单击单元格,进入编辑状态,可以看到如下界面:

以上内容是小编给大家介绍的c#自定义datagridviewcolumn显示treeview 的全部叙述,希望大家喜欢。

dy("nrwz");

查看更多关于C#自定义DataGridViewColumn显示TreeView的详细内容...

  阅读:89次