【问题标题】:How do I know when a WindowsFormsHost is resizing in WPF?我如何知道 WindowsFormsHost 何时在 WPF 中调整大小?
【发布时间】:2009-02-04 22:58:18
【问题描述】:

我在 WindowsFormsHost 中有一个 Windows 窗体映射,我需要它来调整窗口大小。

我只是不确定要听什么事件来执行此操作。我需要地图只在鼠标抬起后才调整大小,否则它会滞后,并在您非常缓慢地调整窗口大小时尝试绘制自己一百万次。

【问题讨论】:

    标签: c# .net wpf xaml


    【解决方案1】:

    等待计时器是一个非常非常糟糕的主意,很简单,这是一种启发式方法,您在猜测调整大小操作何时完成。

    更好的办法是从WindowsFormsHost 派生一个类并覆盖WndProc 方法,处理WM_SIZE 消息。这是在大小操作完成时发送到窗口的消息(与在此过程中发送的WM_SIZING 相反)。

    您还可以处理WM_SIZING 消息,而不是在收到此消息时调用WndProc 的基本实现,以防止消息被处理并让地图一直重绘自身。

    Control 类上的WndProc 方法的文档显示了如何覆盖WndProc 方法:

    http://msdn.microsoft.com/en-us/library/system.windows.forms.control.wndproc(VS.71).aspx

    即使是针对不同的班级,也是完全相同的主体。

    此外,您还需要 WM_SIZINGWM_SIZE 常量的值,您可以在此处找到:

    http://www.pinvoke.net/default.aspx/Enums/WindowsMessages.html

    请注意,您不需要上面链接中的所有内容,只需要这两个值的声明:

    /// <summary>
    /// The WM_SIZING message is sent to a window that
    /// the user is resizing.  By processing this message,
    /// an application can monitor the size and position
    /// of the drag rectangle and, if needed, change its
    /// size or position. 
    /// </summary>
    const int WM_SIZING = 0x0214;
    
    /// <summary>
    /// The WM_SIZE message is sent to a window after its
    /// size has changed.
    /// </summary>
    const int WM_SIZE = 0x0005;
    

    【讨论】:

    • 我删除了我的答案,我并没有试图假设你应该一直运行计时器。不管怎样,我对这种方法很感兴趣。任何链接或示例?
    • pinvoke.net 是你的朋友... =)
    【解决方案2】:

    根据这里的建议:

    http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/8453ab09-ce0e-4e14-b30b-3244b51c13c4

    他们建议使用计时器,并且每次触发 SizeChanged 事件时,您只需重新启动计时器。这样,计时器就不会一直调用“Tick”来检查大小是否发生了变化——每次大小变化,计时器只会关闭一次。也许不太理想,但我不必处理任何低级 Windows 的东西。这种方法也适用于任何 wpf 用户控件,而不仅仅是 wpf 窗口。

    public MyUserControl()
    {
        _resizeTimer.Tick += _resizeTimer_Tick;
    }
    
    DispatcherTimer _resizeTimer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 0, 0, 1500), IsEnabled = false };
    
    private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        _resizeTimer.IsEnabled = true;
        _resizeTimer.Stop();
        _resizeTimer.Start();
    }
    
    int tickCount = 0;
    void _resizeTimer_Tick(object sender, EventArgs e)
    {
        _resizeTimer.IsEnabled = false;
        //you can get rid of this, it just helps you see that this event isn't getting fired all the time
        Console.WriteLine("TICK" + tickCount++);
    
        //Do important one-time resizing work here
        //...
    }
    

    【讨论】:

      猜你喜欢
      • 2010-11-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-04
      • 2011-04-01
      相关资源
      最近更新 更多