最近做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 selectedNodeData; 17 protected T toBeSelected; 18 19 public ComboTreeView(TreeView internalTreeView) 20 { 21 if (null == internalTreeView) 22 { 23 throw new ArgumentNullException("internalTreeView"); 24 } 25 this.InitializeControls(internalTreeView); 26 } 27 28 public event TreeNodeChangedEventHandler TreeNodeChanged; 29 30 protected virtual void InitializeControls(TreeView internalTreeView) 31 { 32 this.treeView = internalTreeView; 33 this.treeView.BorderStyle = BorderStyle.FixedSingle; 34 this.treeView.Margin = new Padding(0); 35 this.treeView.Padding = new Padding(0); 36 this.treeView.AfterExpand += new TreeViewEventHandler(this.WhenAfterExpand); 37 38 this.treeViewHost = new ToolStripControlHost(this.treeView); 39 this.treeViewHost.Margin = new Padding(0); 40 this.treeViewHost.Padding = new Padding(0); 41 this.treeViewHost.AutoSize = false; 42 43 this.dropDown = new ToolStripDropDown(); 44 this.dropDown.Margin = new Padding(0); 45 this.dropDown.Padding = new Padding(0); 46 this.dropDown.AutoSize = false; 47 this.dropDown.DropShadowEnabled = true; 48 this.dropDown.Items.Add(this.treeViewHost); 49 this.dropDown.Closed += new ToolStripDropDownClosedEventHandler(this.OnDropDownClosed); 50 51 this.DropDownWidth = this.Width; 52 base.DropDownStyle = ComboBoxStyle.DropDownList; 53 base.SizeChanged += new EventHandler(this.WhenComboboxSizeChanged); 54 } 55 56 public new ComboBoxStyle DropDownStyle 57 { 58 get { return base.DropDownStyle; } 59 set { base.DropDownStyle = ComboBoxStyle.DropDownList; } 60 } 61 62 public virtual TreeNode SelectedNode 63 { 64 get { return this.selectedNode; } 65 private set { this.treeView.SelectedNode = value; } 66 } 67 68 public virtual T SelectedNodeData 69 { 70 get { return this.selectedNodeData; } 71 set 72 { 73 this.selectedNodeData = value; 74 this.toBeSelected = value; 75 this.UpdateComboBox(value); 76 } 77 } 78 79 protected new int SelectedIndex 80 { 81 get { return base.SelectedIndex; } 82 set { base.SelectedIndex = value; } 83 } 84 85 protected new object SelectedItem 86 { 87 get { return base.SelectedItem; } 88 set { base.SelectedItem = value; } 89 } 90 91 public virtual string DisplayMember { get; set; } = "Name"; 92 93 /// <summary>Gets the internal TreeView control.</summary> 94 public virtual TreeView TreeView => this.treeView; 95 96 /// <summary>Gets the collection of tree nodes that are assigned to the tree view control.</summary> 97 /// <returns>A <see cref="T:System.Windows.Forms.TreeNodeC