Как проверить, продолжается ли изменение размера с событием OnResize? - PullRequest
1 голос
/ 24 января 2010

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

Мой элемент управления наследует класс элемента управления , и я переопределяю событие OnResize .

PS: OnSizeChanged абсолютно одинаков

Ответы [ 4 ]

8 голосов
/ 24 января 2010

Позвольте мне представить альтернативный взгляд на эту проблему:

Проблема не обязательно в том, что «пользователь все еще изменяет размер элемента управления». Реальная проблема заключается в том, что размер элемента управления изменяется чаще, чем время, необходимое для перерисовки.

Если вы определите проблему как одну из пропускная способность , решение станет проще. И на самом деле у Бибопа была правильная идея с его ответом, но я думаю, что мы можем добиться большего:

public class MyControl : Control
{
    private TimeSpan paintTime = 250;   // Time to paint, default=250ms
    private TimeSpan resizeTime = 100;  // Time to update layout, default=100ms

    protected override void OnPaint(PaintEventArgs pe)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        // Do your painting here, or call base.OnPaint
        sw.Stop();
        paintTime = sw.Elapsed;
    }

    protected override void OnResize(EventArgs e)
    {
        // The "Stop" is not redundant - it will force the timer to "reset"
        // if it is already running.
        resizeTimer.Stop();
        base.OnResize(e);
        resizeTimer.Interval =
            (int)(paintTime.TotalMilliseconds + resizeTime.TotalMilliseconds);
        resizeTimer.Start();
    }

    private void UpdateSize()
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        // Resizing code goes here
        sw.Stop();
        resizeTime = sw.Elapsed;
    }

    private void resizeTimer_Tick(object sender, EventArgs e)
    {
        resizeTimer.Stop();
        UpdateSize();
    }
}

Идея в том, чтобы элемент управления активно профилировался; если вы запускаете его на медленной машине или машина просто работает медленно, это замедлит скорость перерисовки. Если вы используете его на новейшем оборудовании, возможно, вам вообще не придется пропускать какие-либо перерисовки. На самом деле это довольно простой алгоритм «автоматического пропуска кадров», который вы часто видите в эмуляторах устройств.

Чтобы было ясно, я ничего не имею против подхода, отстаиваемого nobugz; единственная причина, по которой я бы выбрал этот вариант, заключается в том, что логика полностью автономна, в то время как предоставление свойства Resizing (или, возможно, более метко названного EnableFullPaint) зависит от того, чтобы потребитель знал и использовал его правильно - а также предотвращает перерисовку любых на весь период изменения размера, что может привести к тому, что приложение будет «чувствовать себя» глючно - пользователи не склонны ожидать пустой / бессмысленный экран во время операции изменения размера.

Я использовал оба метода, и они оба работают; какой из них лучше для вас, зависит от ваших требований. Я предлагаю вам попробовать это, посмотреть, насколько хорошо это работает для вас, и если это становится проблематичным или не то, что вы хотите, тогда ответьте nobugz '.

2 голосов
/ 24 января 2010

Одним из решений может быть изменение размера вашего элемента управления только после завершения изменения размера родительского элемента управления / формы. Вы можете сделать это, используя событие ResizeEnd.

Например:

private void UserControl1_Load(object sender, EventArgs e)
{
    ((Form)this.Parent).ResizeEnd += new EventHandler(UserControl1_ResizeEnd);
}
void UserControl1_ResizeEnd(object sender, EventArgs e)
{
    MessageBox.Show("Resize end");
}
1 голос
/ 24 января 2010

Как насчет того, когда вы получаете событие MouseDown go: YourControl.SuspendLayout ();

и затем в событии MouseUp перейдите: YourControl.ResumeLayout ();

0 голосов
/ 24 января 2010

Событие ResizeEnd кажется лучшей идеей, но в качестве альтернативы у вас может быть таймер, который вы перезапускаете в событии resize, и перерисовывает при запуске таймера. Пока время таймера довольно короткое, скажем, 100 мс, вы не должны слишком сильно замечать задержку перерисовки.

Но другое событие кажется лучшим вариантом ...

...