当前位置:编程学习 > C#/ASP.NET >>

C# 如何让treeview 控件中的选中节点闪烁?

C#  如何让treeview 控件中的选中节点闪烁? --------------------编程问答-------------------- 给选中节点加图片,图片闪节点就闪 --------------------编程问答-------------------- winform的么?是的话可以写个例子给你看看 --------------------编程问答-------------------- 继承一个TreeView
用一个Timer然后自绘选中的节点。 --------------------编程问答--------------------
这个小程序实现代码如下:

using System;
using System.Drawing;
using System.Windows.Forms;
namespace BlinkTreeNodeDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Load += new EventHandler(Form1_Load);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            SetupBlinkTreeView();
        }

        private void SetupBlinkTreeView()
        {
            while (!this.IsHandleCreated) ;
            //每秒闪烁一次
            BlinkTreeNodeRenderer bt1 = new BlinkTreeNodeRenderer(treeView1, 1);
            //每秒闪烁10次
            BlinkTreeNodeRenderer bt2 = new BlinkTreeNodeRenderer(treeView2, 10);
            //每秒闪烁25次
            BlinkTreeNodeRenderer bt3 = new BlinkTreeNodeRenderer(treeView3, 25);
        }
    }

    public class BlinkTreeNodeRenderer
    {
        private TreeView treeView;
        private System.Threading.Thread th;

        private int blinkRate;
        private bool isBlink = false;

        public BlinkTreeNodeRenderer(TreeView treeView)
        {
            Initialize(treeView, 1);
        }

        public BlinkTreeNodeRenderer(TreeView treeView, int blinkRate)
        {
            Initialize(treeView, blinkRate);
        }

        private void Initialize(TreeView treeView, int blinkRate)
        {
            if (blinkRate < 0 || blinkRate > 1000)
            {
                throw new ArgumentOutOfRangeException("blinkRate", "blinkRate应大于0且小于1000");
            }

            this.treeView = treeView;
            this.blinkRate = blinkRate;

            this.treeView.HideSelection = false;
            this.treeView.DrawMode = TreeViewDrawMode.OwnerDrawText;
            this.treeView.DrawNode += new DrawTreeNodeEventHandler(treeView_DrawNode);
            this.treeView.Disposed += new EventHandler(treeView_Disposed);

            this.th = new System.Threading.Thread(new System.Threading.ThreadStart(Blink));
            this.th.IsBackground = true;
            this.th.Start();
        }

        //一定的时间间隔更改isBlink的值,并使当前选择节点区域无效(不用对整个控件无效),发送绘制消息
        private void Blink()
        {
            int sleepTime = 1000 / blinkRate;
            while (true)
            {
                System.Threading.Thread.Sleep(sleepTime);
                isBlink = !isBlink;
                treeView.BeginInvoke(new MethodInvoker(delegate()
                {
                    if (treeView.SelectedNode != null && treeView.Focused)
                    {
                        treeView.Invalidate(treeView.SelectedNode.Bounds);
                    }
                }));
            }
        }

        private void treeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
        {
            //设置为false由用户绘制而非操作系统绘制
            e.DrawDefault = false;
            if ((e.State & TreeNodeStates.Selected) != 0 || (e.State & TreeNodeStates.Focused) != 0)
            {
                //判断节点是否已选择或者已获得焦点,如果是true则绘制高亮显示、焦点框
                e.Graphics.FillRectangle(new SolidBrush(SystemColors.Highlight), e.Bounds);
                using (Pen focusedPen = new Pen(Color.Black))
                {
                    focusedPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                    Rectangle focusedBounds = e.Bounds;
                    focusedBounds.Size = new Size(e.Bounds.Width - 1, e.Bounds.Height - 1);
                    e.Graphics.DrawRectangle(focusedPen, focusedBounds);
                }
                //节点根据isBlink状态绘制显示文本
                if (isBlink || !treeView.Focused)
                {
                    TextRenderer.DrawText(e.Graphics, e.Node.Text, e.Node.NodeFont, e.Bounds, Color.White);
                }
            }
            else
            {
                //绘制未被选择的其余节点
                TextRenderer.DrawText(e.Graphics, e.Node.Text, e.Node.NodeFont, e.Bounds, e.Node.ForeColor);
            }
        }

        private void treeView_Disposed(object sender, EventArgs e)
        {
            th.Abort();
            th = null;
        }
    }
}
--------------------编程问答-------------------- if (blinkRate <= 0 || blinkRate > 1000) --------------------编程问答-------------------- 改一改文字(例如改成空白),通过定时器在三分之一秒钟再改回来。反复几次之后,结束这个过程。

例如在你的窗口弄一个Interval等于0.333秒的定时器(Time1),然后如果要改某个特定的Node,可以这样写

    Private nd As TreeNode
    Private ct As Integer

    Private Sub TestButton1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        nd = Me.TreeView1.Nodes(1).Nodes(0).Nodes(0)   '选择你要测试的node
        ct = 0
        Timer1.Start()
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        If (nd.Text = String.Empty) Then
            nd.Text = "Asfasfasfad"
            nd.ForeColor = Color.Red
        Else
            nd.Text = String.Empty
        End If
        If ct > 10 And nd.Text <> String.Empty Then
            nd.ForeColor = Color.Black
            Timer1.Stop()
        Else
            ct += 1
        End If
    End Sub
--------------------编程问答--------------------
引用 4 楼 hwenycocodq520 的回复:

这个小程序实现代码如下:

using System;
using System.Drawing;
using System.Windows.Forms;
namespace BlinkTreeNodeDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Load += new EventHandler(Form1_Load);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            SetupBlinkTreeView();
        }

        private void SetupBlinkTreeView()
        {
            while (!this.IsHandleCreated) ;
            //每秒闪烁一次
            BlinkTreeNodeRenderer bt1 = new BlinkTreeNodeRenderer(treeView1, 1);
            //每秒闪烁10次
            BlinkTreeNodeRenderer bt2 = new BlinkTreeNodeRenderer(treeView2, 10);
            //每秒闪烁25次
            BlinkTreeNodeRenderer bt3 = new BlinkTreeNodeRenderer(treeView3, 25);
        }
    }

    public class BlinkTreeNodeRenderer
    {
        private TreeView treeView;
        private System.Threading.Thread th;

        private int blinkRate;
        private bool isBlink = false;

        public BlinkTreeNodeRenderer(TreeView treeView)
        {
            Initialize(treeView, 1);
        }

        public BlinkTreeNodeRenderer(TreeView treeView, int blinkRate)
        {
            Initialize(treeView, blinkRate);
        }

        private void Initialize(TreeView treeView, int blinkRate)
        {
            if (blinkRate < 0 || blinkRate > 1000)
            {
                throw new ArgumentOutOfRangeException("blinkRate", "blinkRate应大于0且小于1000");
            }

            this.treeView = treeView;
            this.blinkRate = blinkRate;

            this.treeView.HideSelection = false;
            this.treeView.DrawMode = TreeViewDrawMode.OwnerDrawText;
            this.treeView.DrawNode += new DrawTreeNodeEventHandler(treeView_DrawNode);
            this.treeView.Disposed += new EventHandler(treeView_Disposed);

            this.th = new System.Threading.Thread(new System.Threading.ThreadStart(Blink));
            this.th.IsBackground = true;
            this.th.Start();
        }

        //一定的时间间隔更改isBlink的值,并使当前选择节点区域无效(不用对整个控件无效),发送绘制消息
        private void Blink()
        {
            int sleepTime = 1000 / blinkRate;
            while (true)
            {
                System.Threading.Thread.Sleep(sleepTime);
                isBlink = !isBlink;
                treeView.BeginInvoke(new MethodInvoker(delegate()
                {
                    if (treeView.SelectedNode != null && treeView.Focused)
                    {
                        treeView.Invalidate(treeView.SelectedNode.Bounds);
                    }
                }));
            }
        }

        private void treeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
        {
            //设置为false由用户绘制而非操作系统绘制
            e.DrawDefault = false;
            if ((e.State & TreeNodeStates.Selected) != 0 || (e.State & TreeNodeStates.Focused) != 0)
            {
                //判断节点是否已选择或者已获得焦点,如果是true则绘制高亮显示、焦点框
                e.Graphics.FillRectangle(new SolidBrush(SystemColors.Highlight), e.Bounds);
                using (Pen focusedPen = new Pen(Color.Black))
                {
                    focusedPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                    Rectangle focusedBounds = e.Bounds;
                    focusedBounds.Size = new Size(e.Bounds.Width - 1, e.Bounds.Height - 1);
                    e.Graphics.DrawRectangle(focusedPen, focusedBounds);
                }
                //节点根据isBlink状态绘制显示文本
                if (isBlink || !treeView.Focused)
                {
                    TextRenderer.DrawText(e.Graphics, e.Node.Text, e.Node.NodeFont, e.Bounds, Color.White);
                }
            }
            else
            {
                //绘制未被选择的其余节点
                TextRenderer.DrawText(e.Graphics, e.Node.Text, e.Node.NodeFont, e.Bounds, e.Node.ForeColor);
            }
        }

        private void treeView_Disposed(object sender, EventArgs e)
        {
            th.Abort();
            th = null;
        }
    }
}

gif图是怎么截下来的,好清晰 --------------------编程问答-------------------- 在前面加个Gif动态图不是更好 吗,还写这么多的代码 --------------------编程问答-------------------- 非常感谢楼上的各位!! --------------------编程问答--------------------
引用 2 楼 hwenycocodq520 的回复:
winform的么?是的话可以写个例子给你看看


因为你的精彩回答,给推荐下 --------------------编程问答--------------------
引用 8 楼 pinke8 的回复:
在前面加个Gif动态图不是更好 吗,还写这么多的代码


这样比代码来的效率高 --------------------编程问答--------------------
引用 2 楼 hwenycocodq520 的回复:
winform的么?是的话可以写个例子给你看看
--------------------编程问答--------------------
引用 7 楼 chaoyangzhixue 的回复:
gif图是怎么截下来的,好清晰


使用 GifMaker这个小工具~ --------------------编程问答--------------------
引用 8 楼 pinke8 的回复:
在前面加个Gif动态图不是更好 吗,还写这么多的代码

对啊,可以有多个解决方案 --------------------编程问答-------------------- 好啊,长知识了 --------------------编程问答-------------------- --------------------编程问答-------------------- 除 --------------------编程问答-------------------- good,錄點子 --------------------编程问答-------------------- winform的么?是的话可以写个例子给你看看 --------------------编程问答-------------------- 路过来看看   感觉很不错 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- --------------------编程问答-------------------- #4的程序有一个缺点,就是当树控件失去焦点时便不再闪烁节点了,这样的体验很不好,现在修改下程序实现失去焦点时也能正常闪烁,除此之外,还添加了一个属性,即高亮显示与否。

新程序效果图:


代码:

public class BlinkTreeNodeRenderer
{
    private TreeView treeView;
    private System.Threading.Thread th;

    private int blinkRate;
    private bool isBlink = false;

    public bool HightLight { get; set; }

    public BlinkTreeNodeRenderer(TreeView treeView)
    {
        Initialize(treeView, 1);
    }

    public BlinkTreeNodeRenderer(TreeView treeView, int blinkRate, bool hightLight = true)
    {
        Initialize(treeView, blinkRate, hightLight);
    }

    private void Initialize(TreeView treeView, int blinkRate, bool hightLight = true)
    {
        if (blinkRate <= 0 || blinkRate > 1000)
        {
            throw new ArgumentOutOfRangeException("blinkRate", "blinkRate应大于0且小于1000");
        }
        //...略
        this.HightLight = hightLight;
    }

    private void Blink()
    {
        int frameTime = 1000 / blinkRate;
        while (true)
        {
            try
            {
                System.Threading.Thread.Sleep(frameTime);
                isBlink = !isBlink;
                treeView.BeginInvoke(new MethodInvoker(delegate()
                {
                    if (treeView.SelectedNode != null)
                    {
                        if (treeView.Focused)
                            treeView.Invalidate(treeView.SelectedNode.Bounds);
                        else
                            DrawBlinkNode(treeView.SelectedNode);
                    }
                }));
            }
            catch { }
        }
    }

    private void DrawBlinkNode(TreeNode node)
    {
        Graphics g = treeView.CreateGraphics();
        Brush brush = null;
        Pen focusedPen = focusedPen = new Pen(Color.Black);
        Font font = new Font(treeView.Font.FontFamily, treeView.Font.Size);

        if (HightLight)
        {
            brush = new SolidBrush(SystemColors.Highlight);
            g.FillRectangle(brush, node.Bounds);

            focusedPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
            Rectangle focusedBounds = node.Bounds;
            focusedBounds.Size = new Size(node.Bounds.Width - 1, node.Bounds.Height - 1);
            g.DrawRectangle(focusedPen, focusedBounds);
        }
        else
        {
            brush = new SolidBrush(treeView.BackColor);
            g.FillRectangle(brush, node.Bounds);
        }
        if (isBlink)
        {
            TextRenderer.DrawText(g, node.Text, font, node.Bounds,
                HightLight ? Color.White : node.ForeColor);
        }

        font.Dispose();
        focusedPen.Dispose();
        brush.Dispose();
    }

    private void treeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
    {
        e.DrawDefault = false;
        if ((e.State & TreeNodeStates.Selected) != 0 || (e.State & TreeNodeStates.Focused) != 0)
            DrawBlinkNode(e.Node);
        else
            TextRenderer.DrawText(e.Graphics, e.Node.Text, e.Node.NodeFont, e.Bounds, e.Node.ForeColor);
    }
     
    //...略
}
--------------------编程问答-------------------- 除 --------------------编程问答-------------------- 来学习了,非常感谢啊 --------------------编程问答-------------------- 这一下子看好了,这一下子流水账 --------------------编程问答-------------------- 结点和列表怎么结合用? --------------------编程问答-------------------- 楼主,不错哦 --------------------编程问答-------------------- 写的不错!很好!!! --------------------编程问答--------------------
引用 13 楼 hwenycocodq520 的回复:
Quote: 引用 7 楼 chaoyangzhixue 的回复:

gif图是怎么截下来的,好清晰


使用 GifMaker这个小工具~


一样,我还是比较关心介个 --------------------编程问答-------------------- GIFmaker和代码都值得学习  --------------------编程问答-------------------- 收藏一下,用的着 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 变个色就挺好了,闪啊闪的头晕。 --------------------编程问答--------------------
引用 35 楼 yuwenge 的回复:
变个色就挺好了,闪啊闪的头晕。
--------------------编程问答--------------------
引用 36 楼 hwenycocodq520 的回复:
Quote: 引用 35 楼 yuwenge 的回复:

变个色就挺好了,闪啊闪的头晕。


话说你贴出修改后的程序,我帮你patch啊。 --------------------编程问答-------------------- 灰常不错的说:) --------------------编程问答--------------------
using System;
using System.Drawing;
using System.Windows.Forms;
namespace BlinkTreeNodeDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Load += new EventHandler(Form1_Load);
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            SetupBlinkTreeView();
        }
 
        private void SetupBlinkTreeView()
        {
            while (!this.IsHandleCreated) ;
            //每秒闪烁一次
            BlinkTreeNodeRenderer bt1 = new BlinkTreeNodeRenderer(treeView1, 1);
            //每秒闪烁10次
            BlinkTreeNodeRenderer bt2 = new BlinkTreeNodeRenderer(treeView2, 10);
            //每秒闪烁25次
            BlinkTreeNodeRenderer bt3 = new BlinkTreeNodeRenderer(treeView3, 25);
        }
    }
 
    public class BlinkTreeNodeRenderer
    {
        private TreeView treeView;
        private System.Threading.Thread th;
 
        private int blinkRate;
        private bool isBlink = false;
 
        public BlinkTreeNodeRenderer(TreeView treeView)
        {
            Initialize(treeView, 1);
        }
 
        public BlinkTreeNodeRenderer(TreeView treeView, int blinkRate)
        {
            Initialize(treeView, blinkRate);
        }
 
        private void Initialize(TreeView treeView, int blinkRate)
        {
            if (blinkRate < 0 || blinkRate > 1000)
            {
                throw new ArgumentOutOfRangeException("blinkRate", "blinkRate应大于0且小于1000");
            }
 
            this.treeView = treeView;
            this.blinkRate = blinkRate;
 
            this.treeView.HideSelection = false;
            this.treeView.DrawMode = TreeViewDrawMode.OwnerDrawText;
            this.treeView.DrawNode += new DrawTreeNodeEventHandler(treeView_DrawNode);
            this.treeView.Disposed += new EventHandler(treeView_Disposed);
 
            this.th = new System.Threading.Thread(new System.Threading.ThreadStart(Blink));
            this.th.IsBackground = true;
            this.th.Start();
        }
 
        //一定的时间间隔更改isBlink的值,并使当前选择节点区域无效(不用对整个控件无效),发送绘制消息
        private void Blink()
        {
            int sleepTime = 1000 / blinkRate;
            while (true)
            {
                System.Threading.Thread.Sleep(sleepTime);
                isBlink = !isBlink;
                treeView.BeginInvoke(new MethodInvoker(delegate()
                {
                    if (treeView.SelectedNode != null && treeView.Focused)
                    {
                        treeView.Invalidate(treeView.SelectedNode.Bounds);
                    }
                }));
            }
        }
 
        private void treeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
        {
            //设置为false由用户绘制而非操作系统绘制
            e.DrawDefault = false;
            if ((e.State & TreeNodeStates.Selected) != 0 || (e.State & TreeNodeStates.Focused) != 0)
            {
                //判断节点是否已选择或者已获得焦点,如果是true则绘制高亮显示、焦点框
                e.Graphics.FillRectangle(new SolidBrush(SystemColors.Highlight), e.Bounds);
                using (Pen focusedPen = new Pen(Color.Black))
                {
                    focusedPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                    Rectangle focusedBounds = e.Bounds;
                    focusedBounds.Size = new Size(e.Bounds.Width - 1, e.Bounds.Height - 1);
                    e.Graphics.DrawRectangle(focusedPen, focusedBounds);
                }
                //节点根据isBlink状态绘制显示文本
                if (isBlink || !treeView.Focused)
                {
                    TextRenderer.DrawText(e.Graphics, e.Node.Text, e.Node.NodeFont, e.Bounds, Color.White);
                }
            }
            else
            {
                //绘制未被选择的其余节点
                TextRenderer.DrawText(e.Graphics, e.Node.Text, e.Node.NodeFont, e.Bounds, e.Node.ForeColor);
            }
        }
 
        private void treeView_Disposed(object sender, EventArgs e)
        {
            th.Abort();
            th = null;
        }
    }
}
--------------------编程问答-------------------- 高手莫非都在用VB.Net???
引用 6 楼 sp1234 的回复:
改一改文字(例如改成空白),通过定时器在三分之一秒钟再改回来。反复几次之后,结束这个过程。

例如在你的窗口弄一个Interval等于0.333秒的定时器(Time1),然后如果要改某个特定的Node,可以这样写

    Private nd As TreeNode
    Private ct As Integer

    Private Sub TestButton1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        nd = Me.TreeView1.Nodes(1).Nodes(0).Nodes(0)   '选择你要测试的node
        ct = 0
        Timer1.Start()
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        If (nd.Text = String.Empty) Then
            nd.Text = "Asfasfasfad"
            nd.ForeColor = Color.Red
        Else
            nd.Text = String.Empty
        End If
        If ct > 10 And nd.Text <> String.Empty Then
            nd.ForeColor = Color.Black
            Timer1.Stop()
        Else
            ct += 1
        End If
    End Sub
--------------------编程问答-------------------- 二楼的回复是最经典的,还用特殊代码就行了。 --------------------编程问答-------------------- 二楼是夜猫子,但还是要说辛苦了 --------------------编程问答-------------------- 学习了 好像很给力的样子哦 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 收藏一下.. --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 哈哈 好高级的样子 --------------------编程问答-------------------- Mark --------------------编程问答-------------------- Mark --------------------编程问答--------------------
引用 6 楼 sp1234 的回复:
改一改文字(例如改成空白),通过定时器在三分之一秒钟再改回来。反复几次之后,结束这个过程。

例如在你的窗口弄一个Interval等于0.333秒的定时器(Time1),然后如果要改某个特定的Node,可以这样写

    Private nd As TreeNode
    Private ct As Integer

    Private Sub TestButton1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        nd = Me.TreeView1.Nodes(1).Nodes(0).Nodes(0)   '选择你要测试的node
        ct = 0
        Timer1.Start()
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        If (nd.Text = String.Empty) Then
            nd.Text = "Asfasfasfad"
            nd.ForeColor = Color.Red
        Else
            nd.Text = String.Empty
        End If
        If ct > 10 And nd.Text <> String.Empty Then
            nd.ForeColor = Color.Black
            Timer1.Stop()
        Else
            ct += 1
        End If
    End Sub

居然是VB? --------------------编程问答--------------------
引用 5 楼 hwenycocodq520 的回复:
if (blinkRate <= 0 || blinkRate > 1000)
你用的什么录屏软件??? --------------------编程问答--------------------
引用 51 楼 jiaoshiyao 的回复:
Quote: 引用 5 楼 hwenycocodq520 的回复:

if (blinkRate <= 0 || blinkRate > 1000)
你用的什么录屏软件???


使用 GifMaker这个小工具 --------------------编程问答-------------------- 人才济济呀哈哈
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,