-
how to design a new tree view control
We recently need a special tree view control that included some Checkbox or Radio controls in some tree node in a VSTO project. Some of complex nodes included checkbox controls or radio controls but others nodes maybe only is a simply tree node in same TreeView control. If we set value of the property named Checkboxes is “true”, all of the node are included a Checkbox in the TreeView controls, otherwise it will have not any checkbox controls.
So I have to redesign a control to implements these features. I decided to inherit directly from the TreeView class instead of create a new class. I overwrite the method named (OnPaint, WndProc, OnResize etc) and add some new method that will draw a CheckBox control or Radio control in a tree node.
public partial class BaseTreeView : TreeView
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
private define#region private define
private Bitmap internalBitmap = null;
private Graphics internalGraphics = null;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// Indicates whether the OnMouseClick event is raised by expand or collapse a tree node.
/// </summary>
private bool isExpandOrCollapseMouseClick;
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
public BaseTreeView()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
InitializeComponent();
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
private method#region private method
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// Dispose the internal object of treeview.
/// </summary>
private void DisposeInternalObject()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (internalGraphics != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
internalGraphics.Dispose();
}
if (internalBitmap != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
internalBitmap.Dispose();
}
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
public method#region public method
protected override void OnAfterExpand(TreeViewEventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
isExpandOrCollapseMouseClick = true;
}
protected override void OnAfterCollapse(TreeViewEventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
isExpandOrCollapseMouseClick = true;
//throw new Exception("The method or operation is not implemented.");
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
/// override the OnResize method
/// </summary>
/// <param name="e"></param>
protected override void OnResize(EventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (internalBitmap == null ||
internalBitmap.Width != Width || internalBitmap.Height != Height)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
if (Width != 0 && Height != 0)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
DisposeInternalObject();
internalBitmap = new Bitmap(Width, Height);
internalGraphics = Graphics.FromImage(internalBitmap);
}
}
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>Occurs when a Windows message is dispatched.</summary>
/// <param name="message">Message to process.</param>
/// <remarks>Overrides WM_PAINT, WM_ERASEBKGND.</remarks>
protected override void WndProc(ref Message message)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
const int WM_PAINT = 0x000F;
const int WM_PRINTCLIENT = 0x0318;
const int WM_ERASEBKGND = 0x0014;
![](/Images/OutliningIndicators/InBlock.gif)
switch (message.Msg)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
case WM_ERASEBKGND:
//removes flicker
return;
![](/Images/OutliningIndicators/InBlock.gif)
case WM_PAINT:
// The designer host does not call OnResize()
if (internalGraphics == null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
OnResize(EventArgs.Empty);
}
![](/Images/OutliningIndicators/InBlock.gif)
//Set up
Win32.RECT updateRect = new Win32.RECT();
if (Win32.GetUpdateRect(message.HWnd, ref updateRect, false) == 0)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
break;
}
![](/Images/OutliningIndicators/InBlock.gif)
Win32.PAINTSTRUCT paintStruct = new Win32.PAINTSTRUCT();
IntPtr screenHdc = Win32.BeginPaint(message.HWnd, ref paintStruct);
using (Graphics screenGraphics = Graphics.FromHdc(screenHdc))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//Draw Internal Graphics
IntPtr hdc = internalGraphics.GetHdc();
Message printClientMessage = Message.Create(Handle, WM_PRINTCLIENT, hdc, IntPtr.Zero);
DefWndProc(ref printClientMessage);
internalGraphics.ReleaseHdc(hdc);
![](/Images/OutliningIndicators/InBlock.gif)
//Add the missing OnPaint() call
OnPaint(new PaintEventArgs(internalGraphics, Rectangle.FromLTRB(
updateRect.left,
updateRect.top,
updateRect.right,
updateRect.bottom)));
![](/Images/OutliningIndicators/InBlock.gif)
//Draw Screen Graphics
screenGraphics.DrawImage(internalBitmap, 0, 0);
}
![](/Images/OutliningIndicators/InBlock.gif)
//Tear down
Win32.EndPaint(message.HWnd, ref paintStruct);
return;
}
base.WndProc(ref message);
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>Occurs when the control is redrawn.</summary>
/// <remarks>Re enable browsing attributes for the Paint Event.</remarks>
[
EditorBrowsableAttribute(EditorBrowsableState.Always),
BrowsableAttribute(true)
]
public new event PaintEventHandler Paint
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
add
{ base.Paint += value; }
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
remove
{ base.Paint -= value; }
}
![](/Images/OutliningIndicators/InBlock.gif)
private void OnPaintChildNode(TreeNode parentNode, PaintEventArgs pe)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (parentNode.Parent != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
OptionTreeNode optionNode = parentNode.Parent as OptionTreeNode;
OptionItemTreeNode optionItem = parentNode as OptionItemTreeNode;
![](/Images/OutliningIndicators/InBlock.gif)
if (optionNode != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (optionNode.IsOptionFolder )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if ( optionItem != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Rectangle rect = new Rectangle(0, 0, 16, 16);
Bitmap bitmap = new Bitmap(16, 16);
Graphics graphics = Graphics.FromImage(bitmap);
if (optionNode.IsCheckBox)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (parentNode.Checked)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
ControlPaint.DrawCheckBox(graphics, rect, ButtonState.Checked | ButtonState.Flat);
}
else
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
ControlPaint.DrawCheckBox(graphics, rect, ButtonState.Normal | ButtonState.Flat);
}
![](/Images/OutliningIndicators/InBlock.gif)
}
else
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (parentNode.Checked)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
ControlPaint.DrawRadioButton(graphics, rect, ButtonState.Checked | ButtonState.Flat);
}
else
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
ControlPaint.DrawRadioButton(graphics, rect, ButtonState.Normal | ButtonState.Flat);
}
}
![](/Images/OutliningIndicators/InBlock.gif)
rect = parentNode.Bounds;
rect.Y = rect.Y + 4;
rect.Height = 16;
rect.Width = 16;
rect.X = rect.X - 40;
pe.Graphics.DrawImage(bitmap, rect);
}
![](/Images/OutliningIndicators/InBlock.gif)
}
}
![](/Images/OutliningIndicators/InBlock.gif)
}
if (parentNode.Nodes == null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
return;
}
foreach (TreeNode node in parentNode.Nodes)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
OnPaintChildNode(node,pe);
}
}
protected override void OnPaint(PaintEventArgs pe)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// TODO: Add custom paint code here
foreach (TreeNode node in this.Nodes)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
OnPaintChildNode(node,pe);
}
base.OnPaint(pe);
![](/Images/OutliningIndicators/InBlock.gif)
}
protected override void OnMouseClick(MouseEventArgs e)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
if (isExpandOrCollapseMouseClick == true)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
isExpandOrCollapseMouseClick = false;
return;
}
![](/Images/OutliningIndicators/InBlock.gif)
TreeNode node = GetNodeAt(e.X, e.Y);
![](/Images/OutliningIndicators/InBlock.gif)
if ((e.X > node.Bounds.Left) && (e.X < node.Bounds.Right) && (e.Y > node.Bounds.Top) && (e.Y < node.Bounds.Bottom))
return;
![](/Images/OutliningIndicators/InBlock.gif)
if (node != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (node.Parent != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
OptionTreeNode optionNode = node.Parent as OptionTreeNode;
if (optionNode != null)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
if (optionNode.IsOptionFolder)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (optionNode.IsCheckBox)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
node.Checked = !node.Checked;
}
else
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
TreeNode parentNode = node.Parent;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
foreach(TreeNode objNode in parentNode.Nodes)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (node.Equals(objNode))
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
objNode.Checked = !objNode.Checked;
}
else
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
objNode.Checked = false;
}
}
}
![](/Images/OutliningIndicators/InBlock.gif)
}
}
}
}
}
}
#endregion
} If any question please reply me.
-
相关阅读:
hadoop——数据清洗测试
本地配置hadoop
从textarea中获取数据后按原样显示
form自动提交
艺术和代码的结合 turtle + python 的结合
python-->微信支付
python-图片流传输(url转换二维码)
python-qrcode-二维码
Java 通过先序中序序列生成二叉树
Java 实现二叉树的构建以及3种遍历方法
-
原文地址:https://www.cnblogs.com/umlchina/p/305508.html
Copyright © 2020-2023
润新知