Событие BeginResize/EndResize для управления на поверхности конструктора WinForms

TL; DR: я хотел бы знать, как я могу создать привязку к событию begin-resize и end-resize для экземпляра элемента управления времени разработки на поверхности конструктора.


Подробности: в частности, я работаю с поверхностью дизайна, созданной с помощью BasicLoader в пространствах имен.NET System.Design и System.Component.Design. В частности, я работаю с экземпляром TableLayoutPanel во время разработки. Этот контроль выставляет SizeChanged событие и Resize событие - увы, как огнь во время операции изменения размера - то есть, в то время как контроль изменения размеров - а также, когда операция изменения размера завершена. Поэтому у меня нет возможности узнать, когда началась операция изменения размера и когда она официально закончилась.

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

Что касается записей, я еще раз посетил BehaviorService и увидел, что он предоставляет BeginDrag, EndDrag и Synchronize- я не вижу в этой службе ничего, что помогло бы мне с событиями BeginResize/EndResize.

Итак, в идеале я хотел бы подписаться на события BeginResize/EndResize для любого экземпляра конструктора элемента управления Winform, но я был бы счастлив, если бы предоставленный ответ охватывал только мою потребность в привязке этих событий к экземпляру конструктора элемента управления TableLayoutPanel...

Какие-нибудь мысли?

1 ответ

Решение

Когда начинается изменение размера, запускается транзакция дизайнера с конкретным описанием, а когда дизайн заканчивается, транзакция закрывается.

Вы можете положиться на TransactionOpened событие IDesignerHost и проверьте TransactionDescription чтобы увидеть, начинается ли это с "Resize", установите флаг resizing к true. Затем вTransactionClosed вы можете проверить, установлен ли флаг true, это означает, что конец изменения размера.

пример

Вот PoC, чтобы показать, как это работает. Добавьте следующий элемент управления в проект Windows Forms и после сборки проекта удалите экземплярMyControlна форме. Затем, если вы попытаетесь изменить размер формы, вы увидитеResize started. а также Resize ended. текст в строке заголовка формы:

Вот код:

using System;
using System.ComponentModel.Design;
using System.Windows.Forms;
public class MyControl : Control
{
    IDesignerHost host;
    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        if(DesignMode)
        {
            host = (IDesignerHost)Site.GetService(typeof(IDesignerHost));
            host.TransactionOpened += Host_TransactionOpened;
            host.TransactionClosed += Host_TransactionClosed;
        }
    }
    bool resizing = false;
    private void Host_TransactionOpened(object sender, EventArgs e)
    {
        if (host?.TransactionDescription?.StartsWith("Resize") == true)
        {
            resizing = true;
            ((Control)host.RootComponent).Text = "Resize Started.";
        }
    }
    private void Host_TransactionClosed(object sender,
        DesignerTransactionCloseEventArgs e)
    {
        if (resizing)
        {
            resizing = false;
            ((Control)host.RootComponent).Text = "Resize ended.";
        }
    }
}

Если вы хотите провести некоторые исследования и разработки, прежде чем использовать это решение, вы можете взглянуть на следующие классы (в основном внутренние) в System.Design сборка: GrabHandleGlyph, ResizeBehavior.

Другие вопросы по тегам