65.9K
CodeProject 正在变化。 阅读更多。
Home

TreeViewColumns 用户控件(精简版)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.87/5 (25投票s)

2009年3月25日

CPOL

2分钟阅读

viewsIcon

116064

downloadIcon

9633

一个带有列的TreeView。

引言

这个项目展示了一个带有列的TreeView用户控件。

背景

现在有很多TreeView控件可以添加列到树节点。大多数这些控件都有大量的代码才能使其工作。如果降低了规格要求,可以采取更简单的方法来提供一个TreeViewColumns 用户控件精简版

该用户控件的核心是由一个TreeView控件和一个ListView控件混合而成。TreeView控件直接位于ListView控件上,隐藏其主体。只有ListView的列标题可见。ListView的列仅用于设置用户控件的列宽、文本对齐方式和列标题。

TreeViewDrawMode属性设置为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

要使用用户控件,您只需要将一些字符串数组添加到每个TreeNodeTag属性中即可。

真的吗?

是的!!

用户控件有两个属性可用于完成此任务。可以通过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。

© . All rights reserved.