我已经动态地将20个图片框添加到面板中,并希望在使用鼠标滚轮时看到面板滚动。为了实现这一点,我尝试在面板控件上将autoscroll设置为true。这是代码。 对于i As Integer = 1到20:
Dim b As New PictureBox()
b.Image = Nothing
b.BorderStyle = BorderStyle.FixedSingle
b.Text = i.ToString()
b.Size = New Size(60, 40)
b.Location = New Point(0, (i * b.Height) - b.Height)
b.Parent = Panel1
Panel1.Controls.Add(b)
Next
我用按钮控制做了同样的事情,它工作得很好。 对于i As Integer = 1到100:
Dim b As New Button()
b.Text = i.ToString()
b.Size = New Size(60, 40)
b.Location = New Point(0, (i * b.Height) - b.Height)
b.Parent = Panel1
Panel1.Controls.Add(b)
Next
它适用于“按钮”控制,但不适用于“图片框”或“标签”控件吗? 如何使用“鼠标滚轮”实现滚动效果?
答案 0 :(得分:6)
当面板或其中的控件具有焦点时,面板会使用鼠标滚轮滚动。您遇到的问题是,当您单击它时,PictureBox和面板都不会获得焦点。如果您在面板上调用select()
,您将看到鼠标滚轮再次开始工作。
一种可能的解决方案是通过处理Control.MouseEnter事件,在鼠标光标进入时选择面板:
void panel1_MouseEnter(object sender, EventArgs e)
{
panel1.select();
}
答案 1 :(得分:3)
“cwick”非常正确,Windows将WM_MOUSWHEEL通知发布到具有焦点的窗口。当您在面板中放置一个按钮时,它可以正常工作,因为它可以获得焦点。接下来发生的事情是Windows一直在寻找一个父控件来接收消息。按钮不关心它,它的父亲是面板,它会愉快地滚动并消费消息。
除了使用子控件处理焦点的能力(您必须覆盖它们并调用SetStyle(ControlStyles.Selectable))之外,您可以考虑更改此消息的处理方式。许多商业应用程序似乎没有这个问题(浏览器,Office应用程序),因为它们只有几个窗口。 WF应用程序通常有很多,每个控件一个。通过在将消息发送到聚焦控件之前提前处理消息来这样做。 IMessageFilter接口允许这样做。此示例代码在鼠标下滚动控件而不是具有焦点的控件:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsApplication1 {
public partial class Form1 : Form, IMessageFilter {
public Form1() {
InitializeComponent();
Application.AddMessageFilter(this);
}
public bool PreFilterMessage(ref Message m) {
if (m.Msg == 0x20a) {
// WM_MOUSEWHEEL, find the control at screen position m.LParam
Point pos = new Point(m.LParam.ToInt32());
IntPtr hWnd = WindowFromPoint(pos);
if (hWnd != IntPtr.Zero && hWnd != m.HWnd && Control.FromHandle(hWnd) != null) {
SendMessage(hWnd, m.Msg, m.WParam, m.LParam);
return true;
}
}
return false;
}
// P/Invoke declarations
[DllImport("user32.dll")]
private static extern IntPtr WindowFromPoint(Point pt);
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
}
}
请注意,此代码对您应用中的任何窗口有效。确保您尝试并验证它不会让用户过多地混淆。