官網 http://www.hzhcontrols.com/ 前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 碼雲:https://gitee.com/kww ...
官網
前提
入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果覺得寫的還行,請點個 star 支持一下吧
來都來了,點個【推薦】再走吧,謝謝
NuGet
Install-Package HZH_Controls
目錄
http://www.hzhcontrols.com/blog-63.html
用處及效果
準備工作
這個是在前面滾動條上完善的,加入了對常用控制項滾動條的美化,實現邏輯是添加一個滾動條控制項,然後覆蓋在滾動條上面,然後實現聯動
繪製滾動條的工作,你可以參考
(六十九)c#Winform自定義控制項-垂直滾動條-HZHControls
開始
添加一個組件ScrollbarComponent,
實現介面IExtenderProvider
1 Dictionary<Control, bool> m_controlCache = new Dictionary<Control, bool>(); 2 public bool CanExtend(object extendee) 3 { 4 if (extendee is ScrollableControl) 5 { 6 ScrollableControl control = (ScrollableControl)extendee; 7 if (control.AutoScroll == true) 8 { 9 return true; 10 } 11 } 12 else if (extendee is TreeView) 13 { 14 TreeView control = (TreeView)extendee; 15 if (control.Scrollable) 16 { 17 return true; 18 } 19 } 20 else if (extendee is TextBox) 21 { 22 TextBox control = (TextBox)extendee; 23 if (control.Multiline && control.ScrollBars != ScrollBars.None) 24 { 25 return true; 26 } 27 } 28 else if (extendee is RichTextBox) 29 { 30 return true; 31 } 32 else if (extendee is ListBox) 33 { 34 return true; 35 } 36 //else if (extendee is ListView) 37 //{ 38 // return true; 39 //} 40 else if (extendee is DataGridView) 41 { 42 return true; 43 } 44 return false; 45 }
添加擴展屬性
1 [Browsable(true), Category("自定義屬性"), Description("是否使用自定義滾動條"), DisplayName("UserCustomScrollbar"), Localizable(true)] 2 public bool GetUserCustomScrollbar(Control control) 3 { 4 if (m_controlCache.ContainsKey(control)) 5 return m_controlCache[control]; 6 return true; 7 } 8 9 public void SetUserCustomScrollbar(Control control, bool blnUserCustomScrollbar) 10 { 11 m_controlCache[control] = blnUserCustomScrollbar; 12 if (!blnUserCustomScrollbar) 13 return; 14 15 if (control is TreeView) 16 { 17 TreeView tv = (TreeView)control; 18 //tv.MouseWheel += tv_MouseWheel; 19 //tv.AfterSelect += tv_AfterSelect; 20 tv.AfterExpand += tv_AfterExpand; 21 tv.AfterCollapse += tv_AfterCollapse; 22 } 23 else if (control is TextBox) 24 { 25 TextBox txt = (TextBox)control; 26 //txt.MouseWheel += txt_MouseWheel; 27 txt.TextChanged += txt_TextChanged; 28 txt.KeyDown += txt_KeyDown; 29 } 30 else if (control is RichTextBox) 31 { 32 RichTextBox txt = (RichTextBox)control; 33 //txt.MouseWheel += txt_MouseWheel; 34 txt.TextChanged += txt_TextChanged; 35 txt.KeyDown += txt_KeyDown; 36 } 37 else if (control is ListBox) 38 { 39 ListBox lb = (ListBox)control; 40 lb.DataSourceChanged += Lb_DataSourceChanged; 41 lb.SelectedIndexChanged += Lb_SelectedIndexChanged; 42 } 43 //else if (control is ListView) 44 //{ 45 // ListView lv = (ListView)control; 46 47 //} 48 else if (control is DataGridView) 49 { 50 DataGridView dgv = (DataGridView)control; 51 dgv.DataSourceChanged += dgv_DataSourceChanged; 52 dgv.RowsAdded += dgv_RowsAdded; 53 dgv.RowsRemoved += dgv_RowsRemoved; 54 dgv.Scroll += dgv_Scroll; 55 } 56 57 control.VisibleChanged += control_VisibleChanged; 58 control.SizeChanged += control_SizeChanged; 59 control.LocationChanged += control_LocationChanged; 60 control.Disposed += control_Disposed; 61 control.MouseWheel += Control_MouseWheel; 62 control_SizeChanged(control, null); 63 }
控制項大小改變的時候處理滾動條顯示
1 void control_SizeChanged(object sender, EventArgs e) 2 { 3 if (ControlHelper.IsDesignMode()) 4 { 5 return; 6 } 7 else 8 { 9 var control = sender as Control; 10 11 bool blnHasVScrollbar = control.IsHandleCreated && (ControlHelper.GetWindowLong(control.Handle, STYLE) & VSCROLL) != 0; 12 bool blnHasHScrollbar = control.IsHandleCreated && (ControlHelper.GetWindowLong(control.Handle, STYLE) & HSCROLL) != 0; 13 if (control is TextBox) 14 { 15 var txt = (TextBox)control; 16 if (txt.ScrollBars == ScrollBars.Both) 17 { 18 blnHasVScrollbar = true; 19 blnHasHScrollbar = true; 20 } 21 else if (txt.ScrollBars == ScrollBars.Vertical) 22 { 23 blnHasVScrollbar = true; 24 blnHasHScrollbar = false; 25 } 26 else if (txt.ScrollBars == ScrollBars.Horizontal) 27 { 28 blnHasVScrollbar = false; 29 blnHasHScrollbar = true; 30 } 31 else 32 { 33 blnHasVScrollbar = false; 34 blnHasHScrollbar = false; 35 } 36 } 37 else if (control is DataGridView) 38 { 39 var dgv = (DataGridView)control; 40 if (dgv.ScrollBars == ScrollBars.Both || dgv.ScrollBars == ScrollBars.Vertical) 41 { 42 int _height = dgv.RowTemplate.Height * dgv.Rows.Count; 43 if (dgv.ColumnHeadersVisible) 44 { 45 _height += dgv.ColumnHeadersHeight; 46 } 47 blnHasVScrollbar = _height > dgv.Height; 48 } 49 if (dgv.ScrollBars == ScrollBars.Both || dgv.ScrollBars == ScrollBars.Horizontal) 50 { 51 int _width = 0; 52 foreach (DataGridViewColumn com in dgv.Columns) 53 { 54 _width += com.Width; 55 } 56 if (dgv.RowHeadersVisible) 57 { 58 _width += dgv.RowHeadersWidth; 59 } 60 blnHasHScrollbar = _width > dgv.Width; 61 } 62 } 63 else if (control is ListView) 64 { 65 if (!((ListView)control).Scrollable) 66 { 67 blnHasVScrollbar = false; 68 blnHasHScrollbar = false; 69 } 70 } 71 if (blnHasVScrollbar) 72 { 73 if (!m_lstVCache.ContainsKey(control)) 74 { 75 if (control.Parent != null) 76 { 77 UCVScrollbar barV = new UCVScrollbar(); 78 barV.SmallChange = 5; 79 barV.Width = SystemInformation.VerticalScrollBarWidth + 1; 80 barV.Scroll += barV_Scroll; 81 m_lstVCache[control] = barV; 82 if (blnHasHScrollbar) 83 { 84 barV.Height = control.Height - barV.Width; 85 } 86 else 87 { 88 barV.Height = control.Height; 89 } 90 SetVMaxNum(control); 91 barV.Location = new System.Drawing.Point(control.Right - barV.Width, control.Top); 92 control.Parent.Controls.Add(barV); 93 int intControlIndex = control.Parent.Controls.GetChildIndex(control); 94 control.Parent.Controls.SetChildIndex(barV, intControlIndex); 95 } 96 } 97 else 98 { 99 if (blnHasHScrollbar) 100 { 101 m_lstVCache[control].Height = control.Height - m_lstVCache[control].Width; 102 } 103 else 104 { 105 m_lstVCache[control].Height = control.Height; 106 } 107 SetVMaxNum(control); 108 } 109 } 110 else 111 { 112 if (m_lstVCache.ContainsKey(control) && m_lstVCache[control].Parent != null) 113 { 114 m_lstVCache[control].Visible = false; 115 } 116 } 117 118 if (blnHasHScrollbar) 119 { 120 if (!m_lstHCache.ContainsKey(control)) 121 { 122 if (control.Parent != null) 123 { 124 UCHScrollbar barH = new UCHScrollbar(); 125 barH.Height = SystemInformation.HorizontalScrollBarHeight + 1; 126 barH.SmallChange = 5; 127 128 barH.Scroll += barH_Scroll; 129 m_lstHCache[control] = barH; 130 if (blnHasHScrollbar) 131 { 132 barH.Width = control.Width - barH.Height; 133 } 134 else 135 { 136 barH.Width = control.Width; 137 } 138 SetHMaxNum(control); 139 barH.Location = new System.Drawing.Point(control.Left, control.Bottom - barH.Height); 140 control.Parent.Controls.Add(barH); 141 int intControlIndex = control.Parent.Controls.GetChildIndex(control); 142 control.Parent.Controls.SetChildIndex(barH, intControlIndex); 143 } 144 } 145 else 146 { 147 if (blnHasHScrollbar) 148 { 149 m_lstHCache[control].Width = control.Width - m_lstHCache[control].Height; 150 } 151 else 152 { 153 m_lstHCache[control].Width = control.Width; 154 } 155 SetHMaxNum(control); 156 } 157 } 158 else 159 { 160 if (m_lstHCache.ContainsKey(control)) 161 { 162 if (m_lstHCache[control].Visible && m_lstHCache[control].Parent != null) 163 { 164 m_lstHCache[control].Visible = false; 165 } 166 } 167 } 168 } 169 ResetScrollLocation(sender); 170 }
修改橫豎滾動條值
1 private void SetVMaxNum(Control control) 2 { 3 if (!m_lstVCache.ContainsKey(control)) 4 return; 5 var intoV = ControlHelper.GetVScrollBarInfo(control.Handle); 6 UCVScrollbar barV = m_lstVCache[control]; 7 if (control is ScrollableControl) 8 { 9 barV.Maximum = intoV.ScrollMax; 10 barV.Visible = intoV.ScrollMax > 0 && intoV.nMax > 0 && intoV.nPage > 0; 11 barV.Value = intoV.nPos; 12 barV.BringToFront(); 13 // barV.Maximum = (control as ScrollableControl).VerticalScroll.Maximum; 14 // barV.Value = (control as ScrollableControl).VerticalScroll.Value; 15 } 16 else if (control is TreeView) 17 { 18 var tv = control as TreeView; 19 barV.Maximum = intoV.ScrollMax * tv.ItemHeight; 20 barV.Visible = intoV.ScrollMax > 0 && intoV.nMax > 0 && intoV.nPage > 0; 21 barV.Value = intoV.nPos * tv.ItemHeight; 22 barV.BringToFront(); 23 24 //barV.Maximum = GetTreeNodeMaxY(control as TreeView) - control.Height; 25 //barV.Value = (control as TreeView).AutoScrollOffset.Y; 26 } 27 else if (control is TextBox) 28 { 29 TextBox txt = (TextBox)control; 30 barV.Maximum = intoV.ScrollMax * txt.PreferredHeight; 31 if (txt.ScrollBars == ScrollBars.Both || txt.ScrollBars == ScrollBars.Vertical) 32 { 33 barV.Visible = true; 34 } 35 else 36 { 37 barV.Visible = false; 38 } 39 barV.Value = intoV.nPos * txt.PreferredHeight; 40 barV.BringToFront(); 41 } 42 else if (control is RichTextBox) 43 { 44 bool blnHasVScrollbar = control.IsHandleCreated && (ControlHelper.GetWindowLong(control.Handle, STYLE) & VSCROLL) != 0; 45 barV.Maximum = intoV.ScrollMax; 46 barV.Visible = blnHasVScrollbar; 47 barV.Value = intoV.nPos; 48 barV.BringToFront(); 49 } 50 else if (control is ListBox) 51 { 52 var lb = control as ListBox; 53 if (intoV.ScrollMax <= 1) 54 { 55 var v = lb.ItemHeight * lb.Items.Count - lb.Height; 56 if (v > 0) 57 barV.Maximum = v; 58 else 59 barV.Maximum = intoV.ScrollMax * lb.ItemHeight; 60 } 61 else 62 { 63 barV.Maximum = intoV.ScrollMax * lb.ItemHeight; 64 } 65 barV.Visible = intoV.ScrollMax > 0 && intoV.nMax > 0 && intoV.nPage > 0; 66 barV.Value = intoV.nPos * lb.ItemHeight; 67 barV.BringToFront(); 68 } 69 else if (control is ListView) 70 { 71 barV.Maximum = intoV.ScrollMax; 72 barV.Visible = intoV.ScrollMax > 0 && intoV.nMax > 0 && intoV.nPage > 0; 73 barV.Value = intoV.nPos; 74 barV.BringToFront(); 75 } 76 else if (control is DataGridView) 77 { 78 bool blnHasVScrollbar = false; 79 var dgv = (DataGridView)control; 80 if (dgv.ScrollBars == ScrollBars.Both || dgv.ScrollBars == ScrollBars.Vertical) 81 { 82 int _height = dgv.RowTemplate.Height * dgv.Rows.Count; 83 if (dgv.ColumnHeadersVisible) 84 { 85 _height += dgv.ColumnHeadersHeight; 86 } 87 blnHasVScrollbar = _height > dgv.Height; 88 } 89 barV.Maximum = dgv.Rows.Count; 90 barV.Visible = blnHasVScrollbar; 91 barV.Value = dgv.FirstDisplayedScrollingRowIndex; ; 92 barV.BringToFront(); 93 } 94 } 95 private void SetHMaxNum(Control control) 96 { 97 if (!m_lstHCache.ContainsKey(control)) 98 return; 99 var intoH = ControlHelper.GetHScrollBarInfo(control.Handle); 100 UCHScrollbar barH = m_lstHCache[control]; 101 if (control is ScrollableControl) 102 { 103 barH.Maximum = intoH.ScrollMax; 104 barH.Visible = intoH.ScrollMax > 0 && intoH.nMax > 0 && intoH.nPage > 0; 105 barH.Value = intoH.nPos; 106 barH.BringToFront(); 107 108 //barH.Maximum = (control as ScrollableControl).HorizontalScroll.Maximum; 109 //barH.Value = (control as ScrollableControl).HorizontalScroll.Value; 110 } 111 else if (control is TreeView) 112 { 113 var tv = control as TreeView; 114 barH.Maximum = intoH.ScrollMax; 115 barH.Visible = intoH.ScrollMax > 0 && intoH.nMax > 0 && intoH.nPage > 0; 116 barH.Value = intoH.nPos; 117 barH.BringToFront(); 118 //barH.Maximum = GetTreeNodeMaxX(control as TreeView); 119 //barH.Value = (control as TreeView).AutoScrollOffset.X; 120 } 121 else if (control is TextBox) 122 { 123 TextBox txt = (TextBox)control; 124 barH.Maximum = intoH.ScrollMax; 125 126 if (txt.ScrollBars == ScrollBars.Both || txt.ScrollBars == ScrollBars.Horizontal) 127 { 128 barH.Visible = true; 129 } 130 else 131 { 132 barH.Visible = false; 133 } 134 135 barH.Value = intoH.nPos; 136 barH.BringToFront(); 137 } 138 else if (control is RichTextBox) 139 { 140 bool blnHasHScrollbar = control.IsHandleCreated && (ControlHelper.GetWindowLong(control.Handle, STYLE) & HSCROLL) != 0; 141 142 barH.Maximum = intoH.ScrollMax; 143 barH.Visible = blnHasHScrollbar; 144 barH.Value = intoH.nPos; 145 barH.BringToFront(); 146 } 147 else if (control is ListBox) 148 { 149 var lb = control as ListBox; 150 barH.Maximum = intoH.ScrollMax * lb.ItemHeight; 151 barH.Visible = intoH.ScrollMax > 0 && intoH.nMax > 0 && intoH.nPage > 0; 152 barH.Value = intoH.nPos * lb.ItemHeight; 153 barH.BringToFront(); 154 } 155 else if (control is ListView) 156 { 157 barH.Maximum = intoH.ScrollMax; 158 barH.Visible = intoH.ScrollMax > 0 && intoH.nMax > 0 && intoH.nPage > 0; 159 barH.Value = intoH.nPos; 160 barH.BringToFront(); 161 } 162 else if (control is DataGridView) 163 { 164 bool blnHasHScrollbar = false; 165 var dgv = (DataGridView)control; 166 int _width = 0; 167 if (dgv.ScrollBars == ScrollBars.Both || dgv.ScrollBars == ScrollBars.Horizontal) 168 { 169 foreach (DataGridViewColumn com in dgv.Columns) 170 {