TreeViewColumns 用户控件(精简版)






4.87/5 (25投票s)
一个带有列的TreeView。
引言
这个项目展示了一个带有列的TreeView用户控件。
背景
现在有很多TreeView控件可以添加列到树节点。大多数这些控件都有大量的代码才能使其工作。如果降低了规格要求,可以采取更简单的方法来提供一个TreeViewColumns 用户控件精简版。
该用户控件的核心是由一个TreeView
控件和一个ListView
控件混合而成。TreeView
控件直接位于ListView
控件上,隐藏其主体。只有ListView
的列标题可见。ListView
的列仅用于设置用户控件的列宽、文本对齐方式和列标题。
TreeView
的DrawMode
属性设置为OwnerDrawAll
,并且一个DrawNode
事件处理程序在TreeNode
旁边绘制列。
private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
e.DrawDefault = true;
Rectangle rect = e.Bounds;
if ((e.State & TreeNodeStates.Selected) != 0)
{
if ((e.State & TreeNodeStates.Focused) != 0)
e.Graphics.FillRectangle(SystemBrushes.Highlight, rect);
else
e.Graphics.FillRectangle(SystemBrushes.Control, rect);
}
else
e.Graphics.FillRectangle(Brushes.White, rect);
e.Graphics.DrawRectangle(SystemPens.Control, rect);
for (int intColumn = 1; intColumn < this.listView1.Columns.Count;
intColumn++)
{
rect.Offset(this.listView1.Columns[intColumn - 1].Width, 0);
rect.Width = this.listView1.Columns[intColumn].Width;
e.Graphics.DrawRectangle(SystemPens.Control, rect);
string strColumnText;
string[] list = e.Node.Tag as string[];
if (list != null && intColumn<=list.Length)
strColumnText = list[intColumn - 1];
else
strColumnText = intColumn + " " + e.Node.Text; // dummy
TextFormatFlags flags = TextFormatFlags.EndEllipsis;
switch(this.listView1.Columns[intColumn].TextAlign)
{
case HorizontalAlignment.Center:
flags |= TextFormatFlags.HorizontalCenter;
break;
case HorizontalAlignment.Left:
flags |= TextFormatFlags.Left;
break;
case HorizontalAlignment.Right:
flags |= TextFormatFlags.Right;
break;
default:
break;
}
rect.Y++;
if ((e.State & TreeNodeStates.Selected) != 0 &&
(e.State & TreeNodeStates.Focused) != 0)
TextRenderer.DrawText(e.Graphics,
strColumnText,
e.Node.NodeFont,
rect,
SystemColors.HighlightText,
flags);
else
TextRenderer.DrawText(e.Graphics,
strColumnText,
e.Node.NodeFont,
rect,
e.Node.ForeColor,
e.Node.BackColor,
flags);
rect.Y--;
}
}
为了给用户控件提供VisualStyles
外观,只需要使用这两行代码:
public TreeViewColumns()
{
InitializeComponent();
this.BackColor = VisualStyleInformation.TextControlBorder;
this.Padding = new Padding(1);
}
用户控件需要的最后一件事是一些事件处理程序,这些处理程序在用户单击用户控件的“行”或“列”时触发。
private void treeView1_Click(object sender, EventArgs e)
{
Point p = this.treeView1.PointToClient(Control.MousePosition);
TreeNode tn = this.treeView1.GetNodeAt(p);
if (tn != null)
this.treeView1.SelectedNode = tn;
}
private void listView1_ColumnWidthChanged(object sender,
ColumnWidthChangedEventArgs e)
{
this.treeView1.Focus();
this.treeView1.Invalidate();
}
private void listView1_ColumnWidthChanging(object sender,
ColumnWidthChangingEventArgs e)
{
this.treeView1.Focus();
this.treeView1.Invalidate();
}
我保持项目简单,这使得其他人更容易通过添加更多功能来扩展控件。它是CodeProject上带有列的最小的TreeView。但是,它是一个“精简版”。所以,如果某些功能在特定条件下无法正常工作,请不要抱怨。
Using the Code
要使用用户控件,您只需要将一些字符串数组添加到每个TreeNode
的Tag
属性中即可。
真的吗?
是的!!
用户控件有两个属性可用于完成此任务。可以通过this.treeViewColumns1.TreeView
属性访问TreeView本身。对于调整列,必须使用this.treeViewColumns1.Columns
属性。请记住,Columns[0]
是为TreeView
本身保留的空间。
添加TreeNode
和列到用户控件的示例
TreeNode treeNode = new TreeNode("test");
treeNode.Tag = new string[] { "col1", "col2" };
this.treeViewColumns1.TreeView.Nodes.Add(treeNode);
关注点
由于这是一个“精简版”控件,您可以将列更改为导致TreeView
看起来混乱的值。因此,您需要添加代码来进行一些边界检查。
历史
截至写作时(2009年3月),已呈现版本1.0.0.0。