* UITreeView: 增加水平滚动条
This commit is contained in:
parent
8f34889655
commit
83ed1fe1c5
Binary file not shown.
@ -43,6 +43,16 @@ namespace Sunny.UI
|
|||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsNull(this Control ctrl)
|
||||||
|
{
|
||||||
|
return ctrl == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsValid(this Control ctrl)
|
||||||
|
{
|
||||||
|
return ctrl != null;
|
||||||
|
}
|
||||||
|
|
||||||
public static Rectangle ScreenRectangle(this Control ctrl)
|
public static Rectangle ScreenRectangle(this Control ctrl)
|
||||||
{
|
{
|
||||||
return ctrl.RectangleToScreen(ctrl.ClientRectangle);
|
return ctrl.RectangleToScreen(ctrl.ClientRectangle);
|
||||||
|
@ -65,6 +65,15 @@ namespace Sunny.UI
|
|||||||
return si;
|
return si;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SCROLLINFO GetHorInfo(IntPtr handle)
|
||||||
|
{
|
||||||
|
SCROLLINFO si = new SCROLLINFO();
|
||||||
|
si.cbSize = Marshal.SizeOf(si);
|
||||||
|
si.fMask = SIF_DISABLENOSCROLL | SIF_ALL;
|
||||||
|
User.GetScrollInfo(handle, User.SB_HORZ, ref si);
|
||||||
|
return si;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置控件滚动条滚动值
|
/// 设置控件滚动条滚动值
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -78,6 +87,19 @@ namespace Sunny.UI
|
|||||||
User.PostMessage(handle, User.WM_VSCROLL, MakeLong(User.SB_THUMBTRACK, highPart: (short)info.nPos), 0);
|
User.PostMessage(handle, User.WM_VSCROLL, MakeLong(User.SB_THUMBTRACK, highPart: (short)info.nPos), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置控件滚动条滚动值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handle">控件句柄</param>
|
||||||
|
/// <param name="value">滚动值</param>
|
||||||
|
public static void SetHorScrollValue(IntPtr handle, int value)
|
||||||
|
{
|
||||||
|
SCROLLINFO info = GetHorInfo(handle);
|
||||||
|
info.nPos = value;
|
||||||
|
User.SetScrollInfo(handle, User.SB_HORZ, ref info, true);
|
||||||
|
User.PostMessage(handle, User.WM_HSCROLL, MakeLong(User.SB_THUMBTRACK, highPart: (short)info.nPos), 0);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 控件向上滚动一个单位
|
/// 控件向上滚动一个单位
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -101,5 +123,11 @@ namespace Sunny.UI
|
|||||||
if (!ctrl.IsHandleCreated) return false;
|
if (!ctrl.IsHandleCreated) return false;
|
||||||
return (Sunny.UI.Win32.User.GetWindowLong(ctrl.Handle, User.GWL_STYLE) & User.WS_VSCROLL) != 0;
|
return (Sunny.UI.Win32.User.GetWindowLong(ctrl.Handle, User.GWL_STYLE) & User.WS_VSCROLL) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsHorizontalScrollBarVisible(Control ctrl)
|
||||||
|
{
|
||||||
|
if (!ctrl.IsHandleCreated) return false;
|
||||||
|
return (Sunny.UI.Win32.User.GetWindowLong(ctrl.Handle, User.GWL_STYLE) & User.WS_HSCROLL) != 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -273,7 +273,7 @@ namespace Sunny.UI
|
|||||||
{
|
{
|
||||||
isScrollUp = up;
|
isScrollUp = up;
|
||||||
largeChange = large;
|
largeChange = large;
|
||||||
timer.Start();
|
//timer.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StopScroll()
|
private void StopScroll()
|
||||||
@ -297,7 +297,7 @@ namespace Sunny.UI
|
|||||||
if (Value > 0)
|
if (Value > 0)
|
||||||
{
|
{
|
||||||
left_state = DrawItemState.Selected;
|
left_state = DrawItemState.Selected;
|
||||||
ScrollLeft(false);
|
ScrollLeft(true);
|
||||||
StartScroll(true, false);
|
StartScroll(true, false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -312,7 +312,7 @@ namespace Sunny.UI
|
|||||||
if (Value < Maximum)
|
if (Value < Maximum)
|
||||||
{
|
{
|
||||||
right_state = DrawItemState.Selected;
|
right_state = DrawItemState.Selected;
|
||||||
ScrollRight(false);
|
ScrollRight(true);
|
||||||
StartScroll(false, false);
|
StartScroll(false, false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -331,7 +331,7 @@ namespace Sunny.UI
|
|||||||
case 5:
|
case 5:
|
||||||
if (Value < Maximum)
|
if (Value < Maximum)
|
||||||
{
|
{
|
||||||
ScrollRight(false);
|
ScrollRight(true);
|
||||||
if (IsPress)
|
if (IsPress)
|
||||||
{
|
{
|
||||||
StartScroll(false, true);
|
StartScroll(false, true);
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
* 2021-08-26: V3.0.6 CheckBoxes增加三态,感谢群友:笑口常开
|
* 2021-08-26: V3.0.6 CheckBoxes增加三态,感谢群友:笑口常开
|
||||||
* 2022-01-05: V3.0.9 TreeNodeStateSync: 节点点击时同步父节点和子节点的状态
|
* 2022-01-05: V3.0.9 TreeNodeStateSync: 节点点击时同步父节点和子节点的状态
|
||||||
* 2022-03-19: V3.1.1 重构主题配色
|
* 2022-03-19: V3.1.1 重构主题配色
|
||||||
|
* 2022-04-01: V3.1.2 增加水平滚动条
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
@ -43,8 +44,10 @@ namespace Sunny.UI
|
|||||||
public sealed class UITreeView : UIPanel, IToolTip
|
public sealed class UITreeView : UIPanel, IToolTip
|
||||||
{
|
{
|
||||||
private UIScrollBar Bar;
|
private UIScrollBar Bar;
|
||||||
|
private UIHorScrollBar HBar;
|
||||||
|
|
||||||
private bool ScrollBarVisible;
|
private bool ScrollBarVisible;
|
||||||
|
private bool HScrollBarVisible;
|
||||||
private TreeViewEx view;
|
private TreeViewEx view;
|
||||||
|
|
||||||
public UITreeView()
|
public UITreeView()
|
||||||
@ -52,6 +55,7 @@ namespace Sunny.UI
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
SetStyleFlags(true, false);
|
SetStyleFlags(true, false);
|
||||||
ShowText = false;
|
ShowText = false;
|
||||||
|
view.HBar = HBar;
|
||||||
SetScrollInfo();
|
SetScrollInfo();
|
||||||
|
|
||||||
view.BeforeCheck += View_BeforeCheck;
|
view.BeforeCheck += View_BeforeCheck;
|
||||||
@ -179,6 +183,14 @@ namespace Sunny.UI
|
|||||||
Bar.HoverColor = uiColor.ButtonFillHoverColor;
|
Bar.HoverColor = uiColor.ButtonFillHoverColor;
|
||||||
Bar.PressColor = uiColor.ButtonFillPressColor;
|
Bar.PressColor = uiColor.ButtonFillPressColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (HBar != null)
|
||||||
|
{
|
||||||
|
HBar.FillColor = uiColor.TreeViewBarFillColor;
|
||||||
|
HBar.ForeColor = uiColor.TreeViewBarForeColor;
|
||||||
|
HBar.HoverColor = uiColor.ButtonFillHoverColor;
|
||||||
|
HBar.PressColor = uiColor.ButtonFillPressColor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void AfterSetFillColor(Color color)
|
protected override void AfterSetFillColor(Color color)
|
||||||
@ -194,6 +206,11 @@ namespace Sunny.UI
|
|||||||
{
|
{
|
||||||
Bar.FillColor = color;
|
Bar.FillColor = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (HBar != null)
|
||||||
|
{
|
||||||
|
HBar.FillColor = color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void AfterSetForeColor(Color color)
|
protected override void AfterSetForeColor(Color color)
|
||||||
@ -535,11 +552,21 @@ namespace Sunny.UI
|
|||||||
view.Width = Width - 4;
|
view.Width = Width - 4;
|
||||||
view.Height = Height - 4;
|
view.Height = Height - 4;
|
||||||
|
|
||||||
if (Bar == null) return;
|
if (Bar != null)
|
||||||
Bar.Top = 2;
|
{
|
||||||
Bar.Left = Width - ScrollBarInfo.VerticalScrollBarWidth() - 2;
|
Bar.Top = 2;
|
||||||
Bar.Width = ScrollBarInfo.VerticalScrollBarWidth();
|
Bar.Left = Width - ScrollBarInfo.VerticalScrollBarWidth() - 2;
|
||||||
Bar.Height = Height - 4;
|
Bar.Width = ScrollBarInfo.VerticalScrollBarWidth();
|
||||||
|
Bar.Height = Height - 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HBar != null)
|
||||||
|
{
|
||||||
|
HBar.Left = 2;
|
||||||
|
HBar.Top = Height - ScrollBarInfo.HorizontalScrollBarHeight() - 2;
|
||||||
|
HBar.Width = Width - (ScrollBarVisible ? ScrollBarInfo.VerticalScrollBarWidth() : 0) - 2 - 2;
|
||||||
|
HBar.Height = ScrollBarInfo.HorizontalScrollBarHeight();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnFontChanged(EventArgs e)
|
protected override void OnFontChanged(EventArgs e)
|
||||||
@ -572,7 +599,7 @@ namespace Sunny.UI
|
|||||||
|
|
||||||
public void SetScrollInfo()
|
public void SetScrollInfo()
|
||||||
{
|
{
|
||||||
if (view == null || Bar == null) return;
|
if (view == null || Bar == null || HBar == null) return;
|
||||||
|
|
||||||
if (Nodes.Count == 0)
|
if (Nodes.Count == 0)
|
||||||
{
|
{
|
||||||
@ -581,8 +608,10 @@ namespace Sunny.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
var si = ScrollBarInfo.GetInfo(view.Handle);
|
var si = ScrollBarInfo.GetInfo(view.Handle);
|
||||||
|
var si1 = ScrollBarInfo.GetHorInfo(view.Handle);
|
||||||
|
|
||||||
SetPos();
|
SetPos();
|
||||||
|
|
||||||
Bar.Maximum = si.ScrollMax;
|
Bar.Maximum = si.ScrollMax;
|
||||||
Bar.Visible = si.ScrollMax > 0 && si.nMax > 0 && si.nPage > 0;
|
Bar.Visible = si.ScrollMax > 0 && si.nMax > 0 && si.nPage > 0;
|
||||||
Bar.Value = si.nPos;
|
Bar.Value = si.nPos;
|
||||||
@ -593,12 +622,24 @@ namespace Sunny.UI
|
|||||||
ScrollBarVisible = Bar.Visible;
|
ScrollBarVisible = Bar.Visible;
|
||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HBar.Maximum = si1.ScrollMax;
|
||||||
|
HBar.Visible = si1.ScrollMax > 0 && si1.nMax > 0 && si1.nPage > 0;
|
||||||
|
HBar.Value = si1.nPos;
|
||||||
|
HBar.BringToFront();
|
||||||
|
|
||||||
|
if (HScrollBarVisible != HBar.Visible)
|
||||||
|
{
|
||||||
|
HScrollBarVisible = HBar.Visible;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeComponent()
|
private void InitializeComponent()
|
||||||
{
|
{
|
||||||
view = new TreeViewEx();
|
view = new TreeViewEx();
|
||||||
Bar = new UIScrollBar();
|
Bar = new UIScrollBar();
|
||||||
|
HBar = new UIHorScrollBar();
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
//
|
//
|
||||||
// view
|
// view
|
||||||
@ -630,9 +671,22 @@ namespace Sunny.UI
|
|||||||
Bar.Visible = false;
|
Bar.Visible = false;
|
||||||
Bar.ValueChanged += Bar_ValueChanged;
|
Bar.ValueChanged += Bar_ValueChanged;
|
||||||
//
|
//
|
||||||
|
// HBar
|
||||||
|
//
|
||||||
|
HBar.Font = new Font("微软雅黑", 12F);
|
||||||
|
HBar.Location = new Point(247, 3);
|
||||||
|
HBar.Name = "HBar";
|
||||||
|
HBar.Size = new Size(173, 19);
|
||||||
|
HBar.Style = UIStyle.Custom;
|
||||||
|
HBar.StyleCustomMode = true;
|
||||||
|
HBar.TabIndex = 3;
|
||||||
|
HBar.Visible = false;
|
||||||
|
HBar.ValueChanged += HBar_ValueChanged;
|
||||||
|
//
|
||||||
// UITreeViewEx
|
// UITreeViewEx
|
||||||
//
|
//
|
||||||
Controls.Add(Bar);
|
Controls.Add(Bar);
|
||||||
|
Controls.Add(HBar);
|
||||||
Controls.Add(view);
|
Controls.Add(view);
|
||||||
FillColor = Color.White;
|
FillColor = Color.White;
|
||||||
Style = UIStyle.Custom;
|
Style = UIStyle.Custom;
|
||||||
@ -644,6 +698,12 @@ namespace Sunny.UI
|
|||||||
ScrollBarInfo.SetScrollValue(view.Handle, Bar.Value);
|
ScrollBarInfo.SetScrollValue(view.Handle, Bar.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HBar_ValueChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
ScrollBarInfo.SetHorScrollValue(view.Handle, HBar.Value);
|
||||||
|
//view.Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
private void view_AfterExpand(object sender, TreeViewEventArgs e)
|
private void view_AfterExpand(object sender, TreeViewEventArgs e)
|
||||||
{
|
{
|
||||||
SetScrollInfo();
|
SetScrollInfo();
|
||||||
@ -666,6 +726,8 @@ namespace Sunny.UI
|
|||||||
|
|
||||||
internal class TreeViewEx : TreeView
|
internal class TreeViewEx : TreeView
|
||||||
{
|
{
|
||||||
|
public UIHorScrollBar HBar;
|
||||||
|
|
||||||
private TreeNode CurrentNode;
|
private TreeNode CurrentNode;
|
||||||
|
|
||||||
private bool showLines;
|
private bool showLines;
|
||||||
@ -757,6 +819,7 @@ namespace Sunny.UI
|
|||||||
{
|
{
|
||||||
DicNodeStatus.Add(e.Node.GetHashCode(), false);
|
DicNodeStatus.Add(e.Node.GetHashCode(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CheckBoxes)
|
if (CheckBoxes)
|
||||||
{
|
{
|
||||||
if (TreeNodeStateSync && e.Node.Parent != null && DicNodeStatus.ContainsKey(e.Node.Parent.GetHashCode()) && !DicNodeStatus[e.Node.Parent.GetHashCode()])
|
if (TreeNodeStateSync && e.Node.Parent != null && DicNodeStatus.ContainsKey(e.Node.Parent.GetHashCode()) && !DicNodeStatus[e.Node.Parent.GetHashCode()])
|
||||||
@ -764,7 +827,11 @@ namespace Sunny.UI
|
|||||||
SetParentNodeCheckedState(e.Node);
|
SetParentNodeCheckedState(e.Node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (BorderStyle == BorderStyle.Fixed3D) BorderStyle = BorderStyle.FixedSingle;
|
|
||||||
|
if (BorderStyle == BorderStyle.Fixed3D)
|
||||||
|
{
|
||||||
|
BorderStyle = BorderStyle.FixedSingle;
|
||||||
|
}
|
||||||
|
|
||||||
if (e.Node == null || e.Node.Bounds.Width <= 0 && e.Node.Bounds.Height <= 0 && e.Node.Bounds.X <= 0 && e.Node.Bounds.Y <= 0)
|
if (e.Node == null || e.Node.Bounds.Width <= 0 && e.Node.Bounds.Height <= 0 && e.Node.Bounds.X <= 0 && e.Node.Bounds.Y <= 0)
|
||||||
{
|
{
|
||||||
@ -772,9 +839,13 @@ namespace Sunny.UI
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int drawLeft;
|
||||||
|
if (!HBar.Visible)
|
||||||
|
drawLeft = e.Bounds.X + (e.Node.Level + 1) * Indent + 3;
|
||||||
|
else
|
||||||
|
drawLeft = -(int)(Width * HBar.Value * 1.0 / HBar.Maximum) + (e.Node.Level + 1) * Indent + 3;
|
||||||
|
|
||||||
var drawLeft = (e.Node.Level + 1) * Indent + 3;
|
var checkBoxLeft = drawLeft - 2;
|
||||||
var checkBoxLeft = (e.Node.Level + 1) * Indent + 1;
|
|
||||||
var imageLeft = drawLeft;
|
var imageLeft = drawLeft;
|
||||||
var haveImage = false;
|
var haveImage = false;
|
||||||
var sf = e.Graphics.MeasureString(e.Node.Text, Font);
|
var sf = e.Graphics.MeasureString(e.Node.Text, Font);
|
||||||
@ -785,8 +856,7 @@ namespace Sunny.UI
|
|||||||
imageLeft += 16;
|
imageLeft += 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImageList != null && ImageList.Images.Count > 0 && e.Node.ImageIndex >= 0 &&
|
if (ImageList != null && ImageList.Images.Count > 0 && e.Node.ImageIndex >= 0 && e.Node.ImageIndex < ImageList.Images.Count)
|
||||||
e.Node.ImageIndex < ImageList.Images.Count)
|
|
||||||
{
|
{
|
||||||
haveImage = true;
|
haveImage = true;
|
||||||
drawLeft += ImageList.ImageSize.Width + 6;
|
drawLeft += ImageList.ImageSize.Width + 6;
|
||||||
@ -834,8 +904,6 @@ namespace Sunny.UI
|
|||||||
|
|
||||||
if (CheckBoxes)
|
if (CheckBoxes)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
if (!e.Node.Checked)
|
if (!e.Node.Checked)
|
||||||
{
|
{
|
||||||
e.Graphics.DrawRectangle(checkboxColor,
|
e.Graphics.DrawRectangle(checkboxColor,
|
||||||
@ -872,7 +940,11 @@ namespace Sunny.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
var lineY = e.Bounds.Y + e.Node.Bounds.Height / 2 - 1;
|
var lineY = e.Bounds.Y + e.Node.Bounds.Height / 2 - 1;
|
||||||
var lineX = 3 + e.Node.Level * Indent + 9;
|
int lineX;
|
||||||
|
if (!HBar.Visible)
|
||||||
|
lineX = 3 + e.Node.Level * Indent + 9;
|
||||||
|
else
|
||||||
|
lineX = -(int)(Width * HBar.Value * 1.0 / HBar.Maximum) + 3 + e.Node.Level * Indent + 9;
|
||||||
|
|
||||||
if (ShowLinesEx)
|
if (ShowLinesEx)
|
||||||
{
|
{
|
||||||
@ -926,7 +998,11 @@ namespace Sunny.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lineX = 3 + e.Node.Level * Indent + 9;
|
if (!HBar.Visible)
|
||||||
|
lineX = 3 + e.Node.Level * Indent + 9;
|
||||||
|
else
|
||||||
|
lineX = -(int)(Width * HBar.Value * 1.0 / HBar.Maximum) + 3 + e.Node.Level * Indent + 9;
|
||||||
|
|
||||||
//绘制左侧+号
|
//绘制左侧+号
|
||||||
if (ShowPlusMinus && e.Node.Nodes.Count > 0)
|
if (ShowPlusMinus && e.Node.Nodes.Count > 0)
|
||||||
{
|
{
|
||||||
@ -981,7 +1057,6 @@ namespace Sunny.UI
|
|||||||
|
|
||||||
private void SetParentNodeCheckedState(TreeNode currNode, bool ByMouse = false)
|
private void SetParentNodeCheckedState(TreeNode currNode, bool ByMouse = false)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (currNode.Parent == null)
|
if (currNode.Parent == null)
|
||||||
return;
|
return;
|
||||||
TreeNode parentNode = currNode.Parent; //获得当前节点的父节点
|
TreeNode parentNode = currNode.Parent; //获得当前节点的父节点
|
||||||
@ -1021,7 +1096,6 @@ namespace Sunny.UI
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//选中节点之后,选中节点的所有子节点
|
//选中节点之后,选中节点的所有子节点
|
||||||
private void SetChildNodeCheckedState(TreeNode currNode, bool state)
|
private void SetChildNodeCheckedState(TreeNode currNode, bool state)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user