如何检测何时滚动了MDIClient窗口 [英] How to detect when an MDIClient window has been scrolled

查看:67
本文介绍了如何检测何时滚动了MDIClient窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用户通过拖动MDIClient的滚动条拇指滚动子窗口时,我需要更新System.Windows.Forms.MDIClient容器中子窗口的位置.

I need to update the position of a child window inside my System.Windows.Forms.MDIClient container when the user scrolls it by dragging the MDIClient's scrollbar thumb.

但是,我找不到发生这种情况时触发的事件.

However I can't find an event that triggers when this happens.

我只是想念它,还是需要一种解决方法,可能是直接与滚动条交谈?

Am I simply missing it, or do I need a workaround, possibly by talking direct to the scrollbar?

我已经尝试处理MDIClient.Layout事件,但是不会被滚动触发.

I've already tried handling MDIClient.Layout events, but they aren't being triggered by scrolling.

实际上,我只需要知道滚动停止的时间,即可更改子窗口的位置.

I actually only need to know when the scrolling has stopped, in order to change my child window's position.

作为一种临时解决方法,我每秒重置计时器上的子窗口位置,这显然不理想,但总比没有好.看起来很糟糕!

As a temporary workaround, I'm resetting the child window position on a timer every second, obviously not ideal, but better than nothing. Looks terrible though!

推荐答案

这是可能的,尽管有点尴尬. Winforms并不容易找到MdiClient窗口,并且类本身不公开Scroll事件.可以解决此问题,就像在Winforms中一样,您必须对父窗口的本机MDI客户端窗口进行子类化,以便捕获WM_VSCROLL消息.这段代码很好用,将其粘贴到您的父表单类中:

That's possible although a bit awkward. Winforms doesn't make it very easy to find the MdiClient window back and the class itself doesn't expose the Scroll event. That can be worked around, as always in Winforms, you have to sub-class the native MDI client window of your parent window so you can capture the WM_VSCROLL message. This code worked well, paste it into your parent form class:

void MdiClient_Scroll(object sender, ScrollEventArgs e) {
    if (e.Type == ScrollEventType.EndScroll) {
        // Do your stuff
        //...
    }
}

private MdiClientWrapper wrapper;

protected override void OnHandleCreated(EventArgs e) {
    // Find the MdiClient and sub-class it so we can get the Scroll event
    base.OnHandleCreated(e);
    if (wrapper != null) wrapper.Scroll -= MdiClient_Scroll;
    var client = this.Controls.OfType<MdiClient>().First();
    wrapper = new MdiClientWrapper();
    wrapper.AssignHandle(client.Handle);
    wrapper.Scroll += MdiClient_Scroll;
}

private class MdiClientWrapper : NativeWindow {
    public event ScrollEventHandler Scroll;
    private int oldPos;
    protected override void WndProc(ref Message m) {
        if (m.Msg == 0x115) {   // Trap WM_VSCROLL
            var type = (ScrollEventType)(m.WParam.ToInt32() & 0xffff);
            var pos = m.WParam.ToInt32() >> 16;
            Scroll(this, new ScrollEventArgs(type, oldPos, pos));
            oldPos = pos;
        }
        base.WndProc(ref m);
    }
}

这篇关于如何检测何时滚动了MDIClient窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆