123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537 |
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms;
- namespace HZH_Controls.Controls
- {
- [ProvideProperty("UserCustomScrollbar", typeof(Control))]
- public class ScrollbarComponent : Component, IExtenderProvider
- {
- public ScrollbarComponent()
- {
- }
- public ScrollbarComponent(IContainer container)
- {
- container.Add(this);
- }
- Dictionary<Control, bool> m_controlCache = new Dictionary<Control, bool>();
- public bool CanExtend(object extendee)
- {
- if (extendee is ScrollableControl)
- {
- ScrollableControl control = (ScrollableControl)extendee;
- if (control.AutoScroll == true)
- {
- return true;
- }
- }
- else if (extendee is TreeView)
- {
- TreeView control = (TreeView)extendee;
- if (control.Scrollable)
- {
- return true;
- }
- }
- else if (extendee is TextBox)
- {
- TextBox control = (TextBox)extendee;
- if (control.Multiline && control.ScrollBars != ScrollBars.None)
- {
- return true;
- }
- }
- return false;
- }
- [Browsable(true), Category("自定义属性"), Description("是否使用自定义滚动条"), DisplayName("UserCustomScrollbar"), Localizable(true)]
- public bool GetUserCustomScrollbar(Control control)
- {
- if (m_controlCache.ContainsKey(control))
- return m_controlCache[control];
- return true;
- }
- public void SetUserCustomScrollbar(Control control, bool blnUserCustomScrollbar)
- {
- m_controlCache[control] = blnUserCustomScrollbar;
- if (!blnUserCustomScrollbar)
- return;
- control.VisibleChanged += control_VisibleChanged;
- control.SizeChanged += control_SizeChanged;
- control.LocationChanged += control_LocationChanged;
- control.Disposed += control_Disposed;
- if (control is TreeView)
- {
- TreeView tv = (TreeView)control;
- tv.MouseWheel += tv_MouseWheel;
- tv.AfterSelect += tv_AfterSelect;
- tv.AfterExpand += tv_AfterExpand;
- tv.AfterCollapse += tv_AfterCollapse;
- }
- else if (control is TextBox)
- {
- TextBox txt = (TextBox)control;
- txt.MouseWheel += txt_MouseWheel;
- txt.TextChanged += txt_TextChanged;
- txt.KeyDown += txt_KeyDown;
- }
- control_SizeChanged(control, null);
- }
- void control_Disposed(object sender, EventArgs e)
- {
- Control control = (Control)sender;
- if (m_lstVCache.ContainsKey(control) && m_lstVCache[control].Parent != null)
- {
- m_lstVCache[control].Parent.Controls.Remove(m_lstVCache[control]);
- m_lstVCache.Remove(control);
- }
- }
- void control_LocationChanged(object sender, EventArgs e)
- {
- ResetScrollLocation(sender);
- }
- void control_SizeChanged(object sender, EventArgs e)
- {
- if (ControlHelper.IsDesignMode())
- {
- return;
- }
- else
- {
- var control = sender as Control;
- bool blnHasVScrollbar = control.IsHandleCreated && (ControlHelper.GetWindowLong(control.Handle, STYLE) & VSCROLL) != 0;
- bool blnHasHScrollbar = control.IsHandleCreated && (ControlHelper.GetWindowLong(control.Handle, STYLE) & HSCROLL) != 0;
- if (blnHasVScrollbar)
- {
- if (!m_lstVCache.ContainsKey(control))
- {
- if (control.Parent != null)
- {
- UCVScrollbar barV = new UCVScrollbar();
- barV.Width = SystemInformation.VerticalScrollBarWidth;
- barV.Scroll += barV_Scroll;
- m_lstVCache[control] = barV;
- if (blnHasHScrollbar)
- {
- barV.Height = control.Height - barV.Width - 2;
- }
- else
- {
- barV.Height = control.Height - 2;
- }
- SetVMaxNum(control);
- barV.Location = new System.Drawing.Point(control.Right - barV.Width - 1, control.Top + 1);
- control.Parent.Controls.Add(barV);
- int intControlIndex = control.Parent.Controls.GetChildIndex(control);
- control.Parent.Controls.SetChildIndex(barV, intControlIndex);
- }
- }
- else
- {
- SetVMaxNum(control);
- }
- }
- else
- {
- if (m_lstVCache.ContainsKey(control) && m_lstVCache[control].Parent != null)
- {
- m_lstVCache[control].Parent.Controls.Remove(m_lstVCache[control]);
- m_lstVCache.Remove(control);
- }
- }
- if (blnHasHScrollbar)
- {
- if (!m_lstHCache.ContainsKey(control))
- {
- if (control.Parent != null)
- {
- UCHScrollbar barH = new UCHScrollbar();
- barH.Height = SystemInformation.HorizontalScrollBarHeight;
- barH.Scroll += barH_Scroll;
- m_lstHCache[control] = barH;
- if (blnHasHScrollbar)
- {
- barH.Width = control.Width - barH.Height - 2;
- }
- else
- {
- barH.Width = control.Width - 2;
- }
- SetHMaxNum(control);
- barH.Location = new System.Drawing.Point(control.Left + 1, control.Bottom - barH.Height - 1);
- control.Parent.Controls.Add(barH);
- int intControlIndex = control.Parent.Controls.GetChildIndex(control);
- control.Parent.Controls.SetChildIndex(barH, intControlIndex);
- }
- }
- else
- {
- SetHMaxNum(control);
- }
- }
- else
- {
- if (m_lstHCache.ContainsKey(control))
- {
- if (m_lstHCache[control].Visible && m_lstHCache[control].Parent != null)
- {
- m_lstHCache[control].Parent.Controls.Remove(m_lstHCache[control]);
- }
- }
- }
- }
- ResetScrollLocation(sender);
- }
- private void SetVMaxNum(Control control)
- {
- if (!m_lstVCache.ContainsKey(control))
- return;
- var into = ControlHelper.GetVScrollBarInfo(control.Handle);
- var intoH = ControlHelper.GetHScrollBarInfo(control.Handle);
- UCVScrollbar barV = m_lstVCache[control];
- if (control is ScrollableControl)
- {
- barV.Maximum = (control as ScrollableControl).VerticalScroll.Maximum;
- barV.Value = (control as ScrollableControl).VerticalScroll.Value;
- }
- else if (control is TreeView)
- {
- barV.Maximum = GetTreeNodeMaxY(control as TreeView);
- barV.Value = (control as TreeView).AutoScrollOffset.Y;
- }
- else if (control is TextBox)
- {
- TextBox txt = (TextBox)control;
- int intTxtMaxHeight = 0;
- int intTextHeight = 0;
- using (var g = txt.CreateGraphics())
- {
- intTxtMaxHeight = (int)g.MeasureString(txt.Text, txt.Font).Height;
- intTextHeight = (int)g.MeasureString(txt.Text.Substring(0, txt.SelectionStart), txt.Font).Height;
- }
- barV.Maximum = intTxtMaxHeight;
- barV.Value = (control as TextBox).AutoScrollOffset.Y;
- }
- }
- private void SetHMaxNum(Control control)
- {
- if (!m_lstHCache.ContainsKey(control))
- return;
- UCHScrollbar barH = m_lstHCache[control];
- if (control is ScrollableControl)
- {
- barH.Maximum = (control as ScrollableControl).HorizontalScroll.Maximum;
- barH.Value = (control as ScrollableControl).HorizontalScroll.Value;
- }
- else if (control is TreeView)
- {
- barH.Maximum = GetTreeNodeMaxX(control as TreeView);
- barH.Value = (control as TreeView).AutoScrollOffset.X;
- }
- else if (control is TextBox)
- {
- TextBox txt = (TextBox)control;
- int intTxtMaxWidth = 0;
- int intTextWidth = 0;
- using (var g = txt.CreateGraphics())
- {
- intTxtMaxWidth = (int)g.MeasureString(txt.Text, txt.Font).Width;
- intTextWidth = (int)g.MeasureString(txt.Text.Substring(0, txt.SelectionStart), txt.Font).Width;
- }
- barH.Maximum = intTxtMaxWidth;
- barH.Value = (control as TextBox).AutoScrollOffset.Y;
- }
- }
- /// <summary>
- /// Resets the v scroll location.
- /// </summary>
- /// <param name="sender">The sender.</param>
- private void ResetScrollLocation(object sender)
- {
- Control control = (Control)sender;
- bool blnHasVScrollbar = control.IsHandleCreated && (ControlHelper.GetWindowLong(control.Handle, STYLE) & VSCROLL) != 0;
- bool blnHasHScrollbar = control.IsHandleCreated && (ControlHelper.GetWindowLong(control.Handle, STYLE) & HSCROLL) != 0;
- if (control.Visible)
- {
- if (m_lstVCache.ContainsKey(control))
- {
- m_lstVCache[control].Location = new System.Drawing.Point(control.Right - m_lstVCache[control].Width - 1, control.Top + 1);
- if (blnHasHScrollbar)
- {
- m_lstVCache[control].Height = control.Height - m_lstVCache[control].Width - 2;
- }
- else
- {
- m_lstVCache[control].Height = control.Height - 2;
- }
- }
- if (m_lstHCache.ContainsKey(control))
- {
- m_lstHCache[control].Location = new System.Drawing.Point(control.Left + 1, control.Bottom - m_lstHCache[control].Height - 1);
- if (blnHasHScrollbar)
- {
- m_lstHCache[control].Width = control.Width - m_lstHCache[control].Height - 2;
- }
- else
- {
- m_lstHCache[control].Width = control.Width - 2;
- }
- }
- }
- }
- /// <summary>
- /// Handles the VisibleChanged event of the control control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
- void control_VisibleChanged(object sender, EventArgs e)
- {
- Control control = (Control)sender;
- if (!control.Visible)
- {
- if (m_lstVCache.ContainsKey(control) && m_lstVCache[control].Parent != null)
- {
- m_lstVCache[control].Parent.Controls.Remove(m_lstVCache[control]);
- m_lstVCache.Remove(control);
- }
- if (m_lstHCache.ContainsKey(control) && m_lstHCache[control].Parent != null)
- {
- m_lstHCache[control].Parent.Controls.Remove(m_lstHCache[control]);
- m_lstHCache.Remove(control);
- }
- }
- }
- private const int HSCROLL = 0x100000;
- private const int VSCROLL = 0x200000;
- private const int STYLE = -16;
- private Dictionary<Control, UCVScrollbar> m_lstVCache = new Dictionary<Control, UCVScrollbar>();
- private Dictionary<Control, UCHScrollbar> m_lstHCache = new Dictionary<Control, UCHScrollbar>();
- void barV_Scroll(object sender, EventArgs e)
- {
- UCVScrollbar bar = (UCVScrollbar)sender;
- if (m_lstVCache.ContainsValue(bar))
- {
- Control c = m_lstVCache.FirstOrDefault(p => p.Value == bar).Key;
- if (c is ScrollableControl)
- {
- (c as ScrollableControl).AutoScrollPosition = new Point((c as ScrollableControl).AutoScrollPosition.X, bar.Value);
- }
- else if (c is TreeView)
- {
- TreeView tv = (c as TreeView);
- SetTreeViewVScrollLocation(tv, tv.Nodes, bar.Value);
- }
- else if (c is TextBox)
- {
- TextBox txt = (c as TextBox);
- SetTextBoxVScrollLocation(txt, bar.Value);
- }
- }
- }
- void barH_Scroll(object sender, EventArgs e)
- {
- UCHScrollbar bar = (UCHScrollbar)sender;
- if (m_lstHCache.ContainsValue(bar))
- {
- Control c = m_lstHCache.FirstOrDefault(p => p.Value == bar).Key;
- if (c is ScrollableControl)
- {
- (c as ScrollableControl).AutoScrollPosition = new Point(bar.Value, (c as ScrollableControl).AutoScrollPosition.Y);
- }
- else if (c is TreeView)
- {
- //TreeView tv = (c as TreeView);
- //SetTreeViewVScrollLocation(tv, tv.Nodes, bar.Value);
- }
- else if (c is TextBox)
- {
- //TextBox txt = (c as TextBox);
- //SetTextBoxVScrollLocation(txt, bar.Value);
- }
- }
- }
- #region Treeview处理 English:Treeview\u5904\u7406
- void tv_AfterCollapse(object sender, TreeViewEventArgs e)
- {
- control_SizeChanged(sender as Control, null);
- }
- void tv_AfterExpand(object sender, TreeViewEventArgs e)
- {
- control_SizeChanged(sender as Control, null);
- }
- /// <summary>
- /// Gets the tree node 最大高度
- /// </summary>
- /// <param name="tv">The tv.</param>
- /// <returns>System.Int32.</returns>
- private int GetTreeNodeMaxY(TreeView tv)
- {
- TreeNode tnLast = tv.Nodes[tv.Nodes.Count - 1];
- begin:
- if (tnLast.IsExpanded && tnLast.Nodes.Count > 0)
- {
- tnLast = tnLast.LastNode;
- goto begin;
- }
- return tnLast.Bounds.Bottom;
- }
- private int GetTreeNodeMaxX(TreeView tv)
- {
- return tv.Nodes.Count != 0 ? tv.Nodes[0].Bounds.Right : 0;
- }
- void tv_AfterSelect(object sender, TreeViewEventArgs e)
- {
- TreeView tv = (TreeView)sender;
- if (m_lstVCache.ContainsKey(tv))
- {
- m_lstVCache[tv].Value = tv.Nodes.Count > 0 ? Math.Abs(tv.Nodes[0].Bounds.Top) : 0;
- }
- }
- void tv_MouseWheel(object sender, MouseEventArgs e)
- {
- TreeView tv = (TreeView)sender;
- if (m_lstVCache.ContainsKey(tv))
- {
- m_lstVCache[tv].Value = tv.Nodes.Count > 0 ? Math.Abs(tv.Nodes[0].Bounds.Top) : 0;
- }
- }
- /// <summary>
- /// Sets the TreeView scroll location.
- /// </summary>
- /// <param name="tv">The tv.</param>
- /// <param name="tns">The TNS.</param>
- /// <param name="intY">The int y.</param>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
- private bool SetTreeViewVScrollLocation(TreeView tv, TreeNodeCollection tns, int intY)
- {
- for (int i = 0; i < tns.Count; i++)
- {
- if (intY >= tns[i].Bounds.Top - tv.Nodes[0].Bounds.Top - 3 && intY <= tns[i].Bounds.Bottom - tv.Nodes[0].Bounds.Top + 3)
- {
- tns[i].EnsureVisible();
- return true;
- }
- else if (tns[i].IsExpanded && tns[i].Nodes.Count > 0)
- {
- bool bln = SetTreeViewVScrollLocation(tv, tns[i].Nodes, intY);
- if (bln)
- return true;
- }
- }
- return false;
- }
- #endregion
- #region TextBox处理 English:TextBox Processing
- void txt_TextChanged(object sender, EventArgs e)
- {
- TextBox txt = sender as TextBox;
- control_SizeChanged(txt, null);
- SetVMaxNum(txt);
- if (m_lstVCache.ContainsKey(txt))
- {
- using (var g = txt.CreateGraphics())
- {
- var size = g.MeasureString(txt.Text.Substring(0, txt.SelectionStart), txt.Font);
- m_lstVCache[txt].Value = (int)size.Height;
- }
- }
- }
- private void SetTextBoxVScrollLocation(TextBox txt, int intY)
- {
- using (var g = txt.CreateGraphics())
- {
- for (int i = 0; i < txt.Lines.Length; i++)
- {
- string str = string.Join("\n", txt.Lines.Take(i + 1));
- var size = g.MeasureString(str, txt.Font);
- if (size.Height >= intY)
- {
- txt.SelectionStart = str.Length;
- txt.ScrollToCaret();
- return;
- }
- }
- }
- }
- void txt_KeyDown(object sender, KeyEventArgs e)
- {
- if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down)
- {
- TextBox txt = (TextBox)sender;
- if (m_lstVCache.ContainsKey(txt))
- {
- using (var g = txt.CreateGraphics())
- {
- var size = g.MeasureString(txt.Text.Substring(0, txt.SelectionStart), txt.Font);
- m_lstVCache[txt].Value = (int)size.Height;
- }
- }
- }
- }
- void txt_MouseWheel(object sender, MouseEventArgs e)
- {
- TextBox txt = (TextBox)sender;
- if (m_lstVCache.ContainsKey(txt))
- {
- using (var g = txt.CreateGraphics())
- {
- StringBuilder str = new StringBuilder();
- for (int i = 0; i < System.Windows.Forms.SystemInformation.MouseWheelScrollLines; i++)
- {
- str.AppendLine("A");
- }
- var height = (int)g.MeasureString(str.ToString(), txt.Font).Height;
- if (e.Delta < 0)
- {
- if (height + m_lstVCache[txt].Value > m_lstVCache[txt].Maximum)
- m_lstVCache[txt].Value = m_lstVCache[txt].Maximum;
- else
- m_lstVCache[txt].Value += height;
- }
- else
- {
- if (m_lstVCache[txt].Value - height < 0)
- m_lstVCache[txt].Value = 0;
- else
- m_lstVCache[txt].Value -= height;
- }
- }
- }
- }
- #endregion
- }
- }
|