当用户通过拖动MDIClient的滚动条滑块滚动它时,我需要更新System.Windows.Forms.MDIClient容器中子窗口的位置。
但是,当发生这种情况时,我找不到触发的事件。
我只是错过了它,或者我是否需要一种解决方法,可能直接与滚动条对话?
我已经尝试过处理MDIClient.Layout事件,但它们并没有被滚动触发。
编辑:我实际上只需要知道滚动何时停止,以便改变我的子窗口的位置。
EDIT2:作为一种临时解决方法,我每秒都会在计时器上重置子窗口位置,显然不理想,但总比没有好。看起来很糟糕!
答案 0 :(得分:2)
尽管有点尴尬,但这是可能的。 Winforms并不容易找到MdiClient窗口,并且类本身不会公开Scroll事件。这可以解决,就像在Winforms中一样,您必须对父窗口的本机MDI客户端窗口进行子类化,以便捕获WM_VSCROLL消息。此代码运行良好,将其粘贴到父表单类中:
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);
}
}