-->

wpf resize complete

2020-08-10 07:48发布

问题:

So I need to procedurally generate a background image for a grid, it only takes .1sec.

So I can wire into the SizeChanged event, but then when you resize the chart, it goes and fires the even maybe 30 times a second, so the resize event lags out signifigantly.

Does anybody know a good way to wire into the resize event and test weather the use is done resizing, I tried simply checking for the mouse up/down state, but when the resize event fires the mouse is pretty much always down.

回答1:

On resize, you could start a short lived timer (say 100 mSec), on each resize reset that timer to prevent it from elapsing. When the last resize happens, the timer will elapse, and you can draw your background image then.

Example:

Timer resizeTimer = new Timer(100) { Enabled = false };

public Window1()
{
    InitializeComponent();
    resizeTimer.Elapsed += new ElapsedEventHandler(ResizingDone);
}

void ResizingDone(object sender, ElapsedEventArgs e)
{
    resizeTimer.Stop();
    GenerateImage();
}

private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
    resizeTimer.Stop();
    resizeTimer.Start();
}


回答2:

Here is the clean solution:

private const int WmExitSizeMove = 0x232;

private void OnLoaded(object sender, RoutedEventArgs args)
{
    var helper = new WindowInteropHelper(this);
    if (helper.Handle != null)
    {
        var source = HwndSource.FromHwnd(helper.Handle);
        if (source != null)
            source.AddHook(HwndMessageHook);
    }
}

private IntPtr HwndMessageHook(IntPtr wnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    switch (msg)
    {
        case WmExitSizeMove:
            // DO SOMETHING HERE
            handled = true;
            break;
    }
    return IntPtr.Zero;
}

Good luck!



回答3:

For .Net 3.5 and later Pete Brown describes a solution with an attached Property using Blends System.Windows.Interactivity.dll.

There you could wire the Resizing event to stop generating your image and in Resized event start to generate the image for the new size.

HTH



回答4:

I would use the Dispatcher.BeginInvoke method. This will ensure that your image is only generated when the application has time to process it.

private bool _generateImageReqested = false;

private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
    if (!_generateImageReqested)
    {
        _generateImageReqested = true;
        Dispatcher.BeginInvoke(new Action(GenerateImage), DispatcherPriority.ApplicationIdle);
    }
}

private void GenerateImage()
{
    _generateImageReqested = false;

    // resize your image here
}


回答5:

Do you need to see the image resizing? You could handle the resize and re-render the image on mouse up event.



回答6:

Best solution is to call "GenerateImage()" twice in the sizechanged eventhandler



标签: .net wpf resize