最近做Winform项目需要用到类似ComboBox的TreeView控件。
虽然各种第三方控件很多,但是存在各种版本不兼容问题。所以自己写了个简单的ComboTreeView控件。
下图是实现效果:
目前实现的比较简单,能满足我项目中的需求。
此处是项目中的代码简化后的版本,供大家参考。
1 using System; 2 using System.Collections.Generic; 3 using System.Windows.Forms; 4 5 namespace CustomControl.Tree 6 { 7 public abstract class ComboTreeView<T> : ComboBox where T : class 8 { 9 protected const int WM_LBUTTONDOWN = 0x0201, WM_LBUTTONDBLCLK = 0x0203; 10 11 protected TreeView treeView; 12 protected ToolStripControlHost treeViewHost; 13 protected ToolStripDropDown dropDown; 14 protected bool dropDownOpen = false; 15 protected TreeNode selectedNode; 16 protected T toBeSelected; 17 18 public ComboTreeView(TreeView internalTreeView) 19 { 20 if (null == internalTreeView) 21 { 22 throw new ArgumentNullException("internalTreeView"); 23 } 24 this.InitializeControls(internalTreeView); 25 } 26 27 public event TreeNodeChangedEventHandler TreeNodeChanged; 28 29 protected virtual void InitializeControls(TreeView internalTreeView) 30 { 31 this.treeView = internalTreeView; 32 this.treeView.BorderStyle = BorderStyle.FixedSingle; 33 this.treeView.Margin = new Padding(0); 34 this.treeView.Padding = new Padding(0); 35 this.treeView.AfterExpand += new TreeViewEventHandler(this.WhenAfterExpand); 36 37 this.treeViewHost = new ToolStripControlHost(this.treeView); 38 this.treeViewHost.Margin = new Padding(0); 39 this.treeViewHost.Padding = new Padding(0); 40 this.treeViewHost.AutoSize = false; 41 42 this.dropDown = new ToolStripDropDown(); 43 this.dropDown.Margin = new Padding(0); 44 this.dropDown.Padding = new Padding(0); 45 this.dropDown.AutoSize = false; 46 this.dropDown.DropShadowEnabled = true; 47 this.dropDown.Items.Add(this.treeViewHost); 48 this.dropDown.Closed += new ToolStripDropDownClosedEventHandler(this.OnDropDownClosed); 49 50 this.DropDownWidth = this.Width; 51 base.DropDownStyle = ComboBoxStyle.DropDownList; 52 base.SizeChanged += new EventHandler(this.WhenComboboxSizeChanged); 53 } 54 55 public new ComboBoxStyle DropDownStyle 56 { 57 get { return base.DropDownStyle; } 58 set { base.DropDownStyle = ComboBoxStyle.DropDownList; } 59 } 60 61 public virtual TreeNode SelectedNode 62 { 63 get { return this.selectedNode; } 64 private set { this.treeView.SelectedNode = value; } 65 } 66 67 public virtual T SelectedNodeData 68 { 69 get { return (T)base.SelectedItem; } 70 set 71 { 72 this.toBeSelected = value; 73 this.UpdateComboBox(value); 74 } 75 } 76 77 protected new int SelectedIndex 78 { 79 get { return base.SelectedIndex; } 80 set { base.SelectedIndex = value; } 81 } 82 83 protected new object SelectedItem 84 { 85 get { return base.SelectedItem; } 86 set { base.SelectedItem = value; } 87 } 88 89 public virtual string DisplayMember { get; set; } = "Name"; 90 91 /// <summary>Gets the internal TreeView control.</summary> 92 public virtual TreeView TreeView => this.treeView; 93 94 /// <summary>Gets the collection of tree nodes that are assigned to the tree view control.</summary> 95 /// <returns>A <see cref="T:System.Windows.Forms.TreeNodeCollection" /> that represents the tree nodes assigned to the tree view cont