C# WinForm 怎样给控件添加滚动条事件?

时间:2022-12-24 17:10:07
我是想在 TreeView 拉动滚动条或者点击滚动条上下小按钮时触发事件。
它本身是没有这个事件的,我想过在鼠标事件中来判断滚动条是否变动,但是当鼠标在滚动条上操作时既不触发控件的鼠标单击事件也不触发窗体的鼠标单击事件所以无从下手。

具体有两个一模一样的treeView,我在左边的操作实时对应到右边,鼠标单击通过sendMessage解决了,鼠标滚轮也通过sendMessage解决了,就差这个滚动条。

有其他办法也行。

8 个解决方案

#1



namespace 模拟鼠标
{
    /// <summary>
    /// TreeView控件名为 myTreeView
    /// 整个都无效,输出窗口也没输出,我看不出来哪里出错了,反正感觉很奇怪
    /// </summary>
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            MyTreeView myTreeView1=new MyTreeView();
            myTreeView1.VScrollEvent+=delegate{
                this.Text="scrolled";
            };
        }
    }
    public class MyTreeView:TreeView{
        public event EventHandler VScrollEvent;
        protected override void WndProc(ref Message m){
            Debug.Print(m.Msg.ToString());
            if(m.Msg==78){
                if(VScrollEvent!=null){
                    VScrollEvent(this,null);
                }
            }
            base.WndProc(ref m);
        }
    }
}

这个是百度知道上得到的回答,但是我自己试了下没反应

#2


自顶。
就剩滚动条不响应了,具体原因就是 0xa2 (WM_NCLBUTTONUP) 无法截取,无奈之下只好把滚动条给禁了。


public bool PreFilterMessage(ref Message m){
if(m.HWnd==treeView1.Handle){
if(m.Msg==0xa1 || m.Msg==0xa3){
return true;
}
virtualMouse.SendMessage(treeView2.Handle,m.Msg,m.WParam,m.LParam);
}
if(m.HWnd==treeView2.Handle){
if(m.Msg==0xa1 || m.Msg==0xa3){
return true;
}
virtualMouse.SendMessage(treeView1.Handle,m.Msg,m.WParam,m.LParam);
}
return false;
}

void MainFormFormClosing(object sender, FormClosingEventArgs e)
{
Application.RemoveMessageFilter(this);
}

void MainFormLoad(object sender, EventArgs e)
{
Application.AddMessageFilter(this);
}

基本算是实现了多控件自动同步操作了。
我擦,最后一次机会,自结帖的节奏啊 C# WinForm 怎样给控件添加滚动条事件?

#3


C# WinForm 怎样给控件添加滚动条事件?
这个思路是对的,但每个控件的这个消息值是不一至。所以只能自结贴了。。。

#4


我的想法是别用  TreeView 自带的滚动条 ,在外面放一个或者在父级Panel上放一个。滚动条事件怎么写都行。

#5


引用 4 楼 dianjixue1 的回复:
我的想法是别用  TreeView 自带的滚动条 ,在外面放一个或者在父级Panel上放一个。滚动条事件怎么写都行。


不起做用的。Panel 也有滚动条的。你把他的AutoScroll设成true就有了。你要查的是Panel的滚动条的消息值是多少
你可以用DEBUG跟踪就能跟踪的出来了。点一下那两个小按钮就输出值是多少就知了

#6


引用 5 楼 wyd1520 的回复:
不起做用的。Panel 也有滚动条的。你把他的AutoScroll设成true就有了。你要查的是Panel的滚动条的消息值是多少
你可以用DEBUG跟踪就能跟踪的出来了。点一下那两个小按钮就输出值是多少就知了

触发滚动条的滚动事件,就不能用TreeView自带的滚动条,采用父级Panel或者外面放置滚动条,关键是计算出TreeView内容的实际高度。这个好算,遍历一下展开节点就可以了。
让TreeView的高度 时刻等于 TreeView内容的实际高度, 如果采用外面放置滚动条就控制TreeView的Top值


#7


我在做的东西是这样的:
左右两个一模一样的TreeView,分别读取两个结构一致但内容稍微有点差别的XML
我想做的是同步操作,就是左边怎么操作右边也跟着一起动
今天突然发现用这种方法来查看XML文档差异简直是智商捉急。。
不过要是能把滚动条的同步也实现就要嘎达了。
大神快粗来

#8


引用 1 楼 shaoerbao 的回复:

namespace 模拟鼠标
{
    /// <summary>
    /// TreeView控件名为 myTreeView
    /// 整个都无效,输出窗口也没输出,我看不出来哪里出错了,反正感觉很奇怪
    /// </summary>
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            MyTreeView myTreeView1=new MyTreeView();
            myTreeView1.VScrollEvent+=delegate{
                this.Text="scrolled";
            };
        }
    }
    public class MyTreeView:TreeView{
        public event EventHandler VScrollEvent;
        protected override void WndProc(ref Message m){
            Debug.Print(m.Msg.ToString());
            if(m.Msg==78){
                if(VScrollEvent!=null){
                    VScrollEvent(this,null);
                }
            }
            base.WndProc(ref m);
        }
    }
}

这个是百度知道上得到的回答,但是我自己试了下没反应

请问treeview的滚动条值是怎么获取到的,是否可以用IMessageFilter。

#1



namespace 模拟鼠标
{
    /// <summary>
    /// TreeView控件名为 myTreeView
    /// 整个都无效,输出窗口也没输出,我看不出来哪里出错了,反正感觉很奇怪
    /// </summary>
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            MyTreeView myTreeView1=new MyTreeView();
            myTreeView1.VScrollEvent+=delegate{
                this.Text="scrolled";
            };
        }
    }
    public class MyTreeView:TreeView{
        public event EventHandler VScrollEvent;
        protected override void WndProc(ref Message m){
            Debug.Print(m.Msg.ToString());
            if(m.Msg==78){
                if(VScrollEvent!=null){
                    VScrollEvent(this,null);
                }
            }
            base.WndProc(ref m);
        }
    }
}

这个是百度知道上得到的回答,但是我自己试了下没反应

#2


自顶。
就剩滚动条不响应了,具体原因就是 0xa2 (WM_NCLBUTTONUP) 无法截取,无奈之下只好把滚动条给禁了。


public bool PreFilterMessage(ref Message m){
if(m.HWnd==treeView1.Handle){
if(m.Msg==0xa1 || m.Msg==0xa3){
return true;
}
virtualMouse.SendMessage(treeView2.Handle,m.Msg,m.WParam,m.LParam);
}
if(m.HWnd==treeView2.Handle){
if(m.Msg==0xa1 || m.Msg==0xa3){
return true;
}
virtualMouse.SendMessage(treeView1.Handle,m.Msg,m.WParam,m.LParam);
}
return false;
}

void MainFormFormClosing(object sender, FormClosingEventArgs e)
{
Application.RemoveMessageFilter(this);
}

void MainFormLoad(object sender, EventArgs e)
{
Application.AddMessageFilter(this);
}

基本算是实现了多控件自动同步操作了。
我擦,最后一次机会,自结帖的节奏啊 C# WinForm 怎样给控件添加滚动条事件?

#3


C# WinForm 怎样给控件添加滚动条事件?
这个思路是对的,但每个控件的这个消息值是不一至。所以只能自结贴了。。。

#4


我的想法是别用  TreeView 自带的滚动条 ,在外面放一个或者在父级Panel上放一个。滚动条事件怎么写都行。

#5


引用 4 楼 dianjixue1 的回复:
我的想法是别用  TreeView 自带的滚动条 ,在外面放一个或者在父级Panel上放一个。滚动条事件怎么写都行。


不起做用的。Panel 也有滚动条的。你把他的AutoScroll设成true就有了。你要查的是Panel的滚动条的消息值是多少
你可以用DEBUG跟踪就能跟踪的出来了。点一下那两个小按钮就输出值是多少就知了

#6


引用 5 楼 wyd1520 的回复:
不起做用的。Panel 也有滚动条的。你把他的AutoScroll设成true就有了。你要查的是Panel的滚动条的消息值是多少
你可以用DEBUG跟踪就能跟踪的出来了。点一下那两个小按钮就输出值是多少就知了

触发滚动条的滚动事件,就不能用TreeView自带的滚动条,采用父级Panel或者外面放置滚动条,关键是计算出TreeView内容的实际高度。这个好算,遍历一下展开节点就可以了。
让TreeView的高度 时刻等于 TreeView内容的实际高度, 如果采用外面放置滚动条就控制TreeView的Top值


#7


我在做的东西是这样的:
左右两个一模一样的TreeView,分别读取两个结构一致但内容稍微有点差别的XML
我想做的是同步操作,就是左边怎么操作右边也跟着一起动
今天突然发现用这种方法来查看XML文档差异简直是智商捉急。。
不过要是能把滚动条的同步也实现就要嘎达了。
大神快粗来

#8


引用 1 楼 shaoerbao 的回复:

namespace 模拟鼠标
{
    /// <summary>
    /// TreeView控件名为 myTreeView
    /// 整个都无效,输出窗口也没输出,我看不出来哪里出错了,反正感觉很奇怪
    /// </summary>
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
            MyTreeView myTreeView1=new MyTreeView();
            myTreeView1.VScrollEvent+=delegate{
                this.Text="scrolled";
            };
        }
    }
    public class MyTreeView:TreeView{
        public event EventHandler VScrollEvent;
        protected override void WndProc(ref Message m){
            Debug.Print(m.Msg.ToString());
            if(m.Msg==78){
                if(VScrollEvent!=null){
                    VScrollEvent(this,null);
                }
            }
            base.WndProc(ref m);
        }
    }
}

这个是百度知道上得到的回答,但是我自己试了下没反应

请问treeview的滚动条值是怎么获取到的,是否可以用IMessageFilter。