How do turn to TableLayoutPanel through an element inside it?



  • Exactly what I mean. I created my control. MyTableLayoutPanelwhich is almost entirely consistent with the base, except for three reassigned events. I redesigned them to make it possible to move the control in shape, that's the code.

    class MyTableLayoutPanel:TableLayoutPanel
    {
        //точка перемещения
        Point DownPoint;
        //нажата ли кнопка мыши
        bool IsDragMode;
    
    protected override void OnMouseDown(MouseEventArgs mevent)
    {
        DownPoint = mevent.Location;
        IsDragMode = true;
        base.OnMouseDown(mevent);
    }
    
    protected override void OnMouseUp(MouseEventArgs mevent)
    {
        IsDragMode = false;
        base.OnMouseUp(mevent);
    }
    
    protected override void OnMouseMove(MouseEventArgs mevent)
    {
        //если кнопка мыши нажата
        if (IsDragMode)
        {
            Point p = mevent.Location;
            //вычисляем разницу в координатах между положением курсора и "нулевой" точкой кнопки
            Point dp = new Point(p.X - DownPoint.X, p.Y - DownPoint.Y);
            Location = new Point(Location.X + dp.X, Location.Y + dp.Y);
        }
        base.OnMouseMove(mevent);
    }
    

    }

    Everything works properly, control moves, no mistakes. Next.
    MyTableLayoutPanel I put pictures or buttons. The question is, in fact, how to press pictures, move MyTableLayoutPanelNot a picture or a button?



  • As such, there is no provision for a routing of events between parents and daughters in WinForms, it is only in WPF. But it is possible to partially simulate the routing of events from the daughter to the parent, and to use this kind of awkward approach:

    public partial class MyTableLayoutPanel:TableLayoutPanel
    {
        public MyTableLayoutPanel()
        {
            InitializeComponent();
            // Подписываемся на событие добавления дочернего контрола
            this.ControlAdded += MyTableLayoutPanel_ControlAdded;
            // Подписываемся на событие удаления дочернего контрола
            this.ControlRemoved += MyTableLayoutPanel_ControlRemoved;   
        }
    

    Developments https://msdn.microsoft.com/ru-ru/library/system.windows.forms.control.controladded(v=vs.110).aspx and https://msdn.microsoft.com/ru-ru/library/system.windows.forms.control.controlremoved(v=vs.110).aspx It works when the subsidiaries are added to the control. We'll use this to keep our hands on the events of the daughter-in-law counters to act on the container.

        void MyTableLayoutPanel_ControlAdded(object sender, ControlEventArgs e)
        {
            // Добавляем свои обработчики к нужным событиям дочернего контрола
            // когда он добавляется в контейнер
            e.Control.MouseUp += MouseUpHandler;
            e.Control.MouseDown += MouseDownHandler;
            e.Control.MouseMove += MouseMoveHandler;
        }
    
    void MyTableLayoutPanel_ControlRemoved(object sender, ControlEventArgs e)
    {
        // Не забываем отписать дочерний контрол от наших обработчиков при его удалении, 
        // чтобы не удерживать ссылку на объект дольше необходимого
        e.Control.MouseUp -= MouseUpHandler;
        e.Control.MouseDown -= MouseDownHandler;
        e.Control.MouseMove -= MouseMoveHandler;
    }
    

    Events are based on delegates, and the delegate retains a reference to the object whose method is transferred to it, so that no memory leaks, we do not forget to deviate from events, when the controller is removed from the parent container. Also in the processor. ContolAddedan additional construction of the characteristics of the subsidiary counters may be carried out.

    Well, we're going to describe the last thing we need to do to run the parent container.

        private void MouseUpHandler(object sender, MouseEventArgs e)
    {
    MouseEventArgs newArgs = new MouseEventArgs(
    e.Button,
    e.Clicks,
    ((Control)sender).Location.X+e.X,
    ((Control)sender).Location.Y+e.Y,
    e.Delta);
    OnMouseUp(newArgs);
    }
    // и так для каждого события, которое нужно передать в родительский контейнер
    }

    If it's done correctly, your daughter's counters will also call the parents' container. Another nuance, the processor of the parent container must carefully verify who called him and transferred the coordinates from the subsidiary ' s coordinates to his own, if of course he receives the coordinates of the event ' s arguments and uses them. Other arguments of the event may also be relevant, so be careful in developing the logic of such coercive processors.

    Also read this one. https://ru.stackoverflow.com/q/475596/198316 there is a proposal for a solution that might be appropriate for your purposes.

    Another solution is to move to WPF and to use the routing of events that are available there without shamanship from the box.




Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2