我感到愚蠢,但我找不到解决问题的方法,我觉得这很容易 我有一个用户控件(基本上)显示在 onPaint 阶段绘制它的图像:
protected override void OnPaint(PaintEventArgs e)
{
if (img != null)
e.Graphics.DrawImage(img, ...);
}
当调整用户控件的大小时,它必须执行许多操作,其中一个是(给定特定条件)调整图像大小以适应宽度或高度等...
显示的图像可能“很重”,因此当用户开始调整大小并移动鼠标时,结果是一种慢速移动,这对最终用户不利。
所以我想知道是否有窗口消息报告我调整大小操作正在开始或完成:如果是这样我可以在调整大小时停止重绘并在调整大小结束时重新绘制图像。
感谢大家
编辑:
我试过这个:
protected override void WndProc(ref Message m)
{
const int WM_ENTERSIZEMOVE = 0x0231;
const int WM_EXITSIZEMOVE = 0x0232;
switch (m.Msg)
{
case WM_ENTERSIZEMOVE: resizing = true; break;
case WM_EXITSIZEMOVE: resizing = false; break;
}
}
但永远不会调用这些消息:(
答案 0 :(得分:2)
您可能会对Form.ResizeBegin和Form.ResizeEnd事件感兴趣。
如果您使用的是WPF,则此thread on MSDN可能会让您感兴趣。 WPF需要hackery才能知道调整大小何时开始/结束
没有注意到它是UserControl!这个问题似乎解决了你的问题: "ResizeEnd" equivalent for usercontrols
答案 1 :(得分:2)
在UserControl的Load事件中,将事件处理程序挂钩到控件表单的事件。
道歉,我打开了一个VB项目,当我得到片刻时,我会在答案中将其转换。
Private Sub UserControl1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
AddHandler Me.FindForm.ResizeBegin, AddressOf MyFormsResizeBegin
AddHandler Me.FindForm.ResizeEnd, AddressOf MyFormsResizeEnd
End Sub
Private Sub MyFormsResizeBegin(sender As Object, e As EventArgs)
'tell your control to wait.
End Sub
Private Sub MyFormsResizeEnd(sender As Object, e As EventArgs)
'say everything is ok to continue
End Sub
答案 2 :(得分:1)
你真的想这样做(Windows消息)? :D
首先,您无法覆盖PreProcessMessage
或WndProc
,因为我猜测包含的表单会捕获调整大小的开始/结束消息(或任何其他消息),因此您的控件将无法获取任何。这样做的方法是在您的控件上实现IMessageFilter
接口。然后,您将在控件中获得此方法,您可以在其中切换收到的消息m:
public bool PreFilterMessage(ref Message m)
然后在控制构造函数中添加:Application.AddMessageFilter(this);
然后你去,现在应用程序线程正在调用PreFilterMessage
方法并将接收到的消息传递给它。
另一个想法:
如果您让用户使用鼠标更改控件大小,您可以捕获MouseDown并设置bool MouseIsDown
标志然后在OnResize
中您可以检查
if(MouseIsDown && Resizing == false)
{
Resizing = true;
//Start Resizing only once
}
在MouseUp上:
if(Resizing == true && MouseIsDown == true)
{
Resizing = MouseIsDown = false;
//End the resizing once
}
答案 3 :(得分:1)
经过长时间的调查,我发了一个答案 首先,我要感谢大家的贡献,因为你的建议让我以正确的方式前进。感谢@Hans Passant,因为他在this post上的解决方案是一个重要的部分。
问题:
EndResize
事件 贡献:
PreProcessMessage
或覆盖WndProc
(感谢@Cipi):MouseDown
和OnResize
事件(感谢@Cipi):Load
事件中,将事件处理程序挂钩到控件表单的事件中(感谢@hometoast和@pikzen):DesignMode
中,他的父母也是如此是 outCnt 的一部分,其父为空,因为没有准备好设置!! <强> SOLUTION:强>
基本上我不得不在 outCnt 中移动@Hans逻辑,而不是在Load
事件中移动,因为即使在这里,父级仍为null!
public class OuterControl
{
protected override void OnParentChanged(EventArgs e)
{
if (!this.DesignMode)
{
Form form = this.FindForm();
if (form != null)
{
form.ResizeBegin += (s, ea) =>innerCnt.Resizing = true;
form.ResizeEnd += (s, ea) => innerCnt.Resizing = false;
}
}
base.OnParentChanged(e);
}
}
public class InnerControl
{
private bool resizing = false;
public bool Resizing {
get { return resizing; };
set {
resizing = value;
if (!resizing) {
// Resizing is just finished:
// let's do what we need
}
}
}
protected override void OnResize(EventArgs e)
{
if (Resizing)
{
base.OnResize(e);
return;
}
else
{
// Perform resizing actions
}
}
}
已知问题:
我很确定如果将 outCnt 放在另一个用户控件中,提供的解决方案将无效...