Как узнать, когда WindowsFormsHost изменяет размеры в WPF? - PullRequest
5 голосов
/ 05 февраля 2009

У меня есть карта оконных форм в WindowsFormsHost, и мне нужно, чтобы она изменила размеры вместе с окном.

Я просто не уверен, какое событие слушать, чтобы сделать это. Мне нужно, чтобы карта изменяла размеры только после того, как мышь нажата, в противном случае она отстает и пытается рисовать себя миллион раз, когда вы очень медленно изменяете размер окна.

Ответы [ 2 ]

7 голосов
/ 05 февраля 2009

Ожидание по таймеру - очень, очень плохая идея, довольно просто, это эвристика, и вы догадываетесь, когда будет выполнена операция изменения размера.

Лучше было бы получить класс из WindowsFormsHost и переопределить метод WndProc, обрабатывая сообщение WM_SIZE. Это сообщение, которое отправляется окну, когда операция размера завершена (в отличие от WM_SIZING, которое отправляется в процессе).

Вы также можете обрабатывать сообщение WM_SIZING и не вызывать базовую реализацию WndProc, когда получаете это сообщение, чтобы предотвратить обработку сообщения и перерисовку карты все это время.

В документации по методу WndProc класса Control показано, как переопределить метод WndProc:

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

Несмотря на то, что это для другого класса, это тот же самый основной принцип.

Кроме того, вам понадобятся значения для констант WM_SIZING и WM_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;
0 голосов
/ 07 марта 2010

По предложению здесь:

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

Они предлагают использовать таймер, и каждый раз, когда происходит событие SizeChanged, вы просто перезапускаете таймер. Таким образом, таймер не вызывает «Tick» все время, чтобы проверить, изменился ли размер - таймер отключается только один раз за изменение размера. Может быть, не идеально, но мне не нужно иметь дело с окнами низкого уровня. Этот подход работает и для любого пользовательского элемента управления 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
    //...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...