【问题标题】:Being able to drag around Dynamically created Panels能够拖动动态创建的面板
【发布时间】:2017-07-31 18:49:58
【问题描述】:

我不断看到有关添加事件以便能够在面板中拖动的帖子。但是我将如何通过动态创建的面板来实现这一点?

Panel pn = wch.GenerateWorkspaceControl(space.Name, space.Name, p);
            PanelTest.Controls.Add(pn);

        public Panel GenerateWorkspaceControl(string gbTitle, string gbName, Point gbPos)
    {
        Panel pnl = GeneratePanelContainer(gbPos, new Size(300, 200));
        pnl.Controls.Add(GenerateLabel(gbName,new Point(100,1),new Size(135,115)));
        return pnl;
    }

private Panel GeneratePanelContainer(Point loc, Size size)
    {
        return new Panel() { BackColor = Color.Transparent, BorderStyle = BorderStyle.FixedSingle, Location = loc, Size = size };
    }

我是否在生成面板容器中添加事件处理程序?

总结一下,我有一个面板,其中包含多个动态创建的面板。我希望能够在主面板内动态创建的面板中移动。

有什么想法吗?

【问题讨论】:

  • 是的,pnl.MouseMove += pnl_MouseMove; 制作该方法,并将发送者对象转换为面板。
  • 您可以为这些面板编写一组事件或 Lambda,或者创建一个向其注册面板的 MoveController 类。 (我更喜欢后者。)

标签: c# events panel


【解决方案1】:

这是一个让您可以使任何控件可移动的类。

只需注册即可:

MoveController.RegisterCtl( button1 );

现在你可以移动控件了..

完成后,您还可以取消注册控件:

MoveController.UnRegisterCtl( button1 );

这是控制器类:

static class MoveController
{
    static List<Control> Controls = new List<Control>();
    static Control curCtl = null;
    static Point curStart = Point.Empty;

    static public void RegisterCtl(Control ctl)
    {
        Controls.Add(ctl);
        ctl.MouseDown += ctl_MouseDown;
        ctl.MouseMove += ctl_MouseMove;
        ctl.MouseUp += ctl_MouseUp;
    }

    static public void UnRegisterCtl(Control ctl)
    {
        if (Controls != null && Controls.Contains(ctl) )
        {
            Controls.Remove(ctl);
            ctl.MouseDown -= ctl_MouseDown;
            ctl.MouseMove -= ctl_MouseMove;
            ctl.MouseUp -= ctl_MouseUp;
        }
    }

    static void ctl_MouseDown(object sender, MouseEventArgs e)
    {
        curCtl = (Control)sender;
        curStart = curCtl.Location;
    }

    static void ctl_MouseMove(object sender, MouseEventArgs e)
    {
        if (curCtl != null)
        {
            curCtl.Left +=  e.Location.X - curCtl.Width / 2;
            curCtl.Top  +=  e.Location.Y - curCtl.Height / 2;
        }
    }

    static void ctl_MouseUp(object sender, MouseEventArgs e)
    {
        curCtl = null;
    }
}

更新

这是一个更复杂的版本,允许

  • 设置Tag 值以限制垂直或水平移动
  • MovingMoved 事件添加Actions..

class MoveController
{
    static List<Control> Controls = new List<Control>();
    static Control curCtl = null;
    static Point curStart = Point.Empty;

    static Dictionary<Control, Tuple<Action, Action>> 
        actions = new Dictionary<Control, Tuple<Action, Action>>();

    static public void RegisterCtl(Control ctl)
    {
        RegisterCtl(ctl, null, null);
    }

    static public void RegisterCtl(Control ctl, Action moveAction, Action movedAction)
    {
        Controls.Add(ctl);
        ctl.MouseEnter += Ctl_MouseEnter;
        ctl.MouseLeave += Ctl_MouseLeave;
        ctl.MouseDown += ctl_MouseDown;
        ctl.MouseMove += ctl_MouseMove;
        ctl.MouseUp += ctl_MouseUp;
        if (moveAction != null)
            if (actions.Keys.Contains(ctl)) actions[ctl] = new Tuple<Action, Action>(moveAction, movedAction);
            else actions.Add(ctl, new Tuple<Action, Action>(moveAction, movedAction));
    }

    private static void Ctl_MouseEnter(object sender, EventArgs e)
    {
        ((Control)sender).Cursor = Cursors.Hand;
    }

    private static void Ctl_MouseLeave(object sender, EventArgs e)
    {
        ((Control)sender).Cursor = Cursors.Default;
    }

    public static void UnRegisterCtl(Control ctl)
    {
        if (Controls != null && Controls.Contains(ctl) )
        {
            Controls.Remove(ctl);
            ctl.MouseDown -= ctl_MouseDown;
            ctl.MouseMove -= ctl_MouseMove;
            ctl.MouseUp -= ctl_MouseUp;
        }
        if (actions.ContainsKey(ctl)) actions.Remove(ctl);
    }



    static public void RegisterMovingAction(Control ctl, Action action)
    {

    }

    static void ctl_MouseDown(object sender, MouseEventArgs e)
    {
        curCtl = (Control)sender;
        curStart = curCtl.Location;
    }

    static void ctl_MouseMove(object sender, MouseEventArgs e)
    {
        int t = 0;
        if (curCtl != null)
        {
            if (curCtl.Tag != null) t = Convert.ToInt32(curCtl.Tag);
            if ((t&1) != 1) curCtl.Left +=  e.Location.X - curCtl.Width / 2;
            if ((t&2) != 2) curCtl.Top  +=  e.Location.Y - curCtl.Height / 2;

            if (actions.ContainsKey(curCtl) && actions[curCtl] != null && actions[curCtl].Item1 != null)
                actions[curCtl].Item1();
        }
    }

    static void ctl_MouseUp(object sender, MouseEventArgs e)
    {
        if (curCtl == null) return;  ///
        if (actions.ContainsKey(curCtl) && actions[curCtl] != null && actions[curCtl].Item2 != null)
            actions[curCtl].Item2();
        curCtl = null;
    }

}

【讨论】:

  • 嘿,谢谢,我做了一些与您的帖子非常相似的事情。从来没有在学校学过这些东西,所以它都是相当新的。另外,我不能发帖是因为人们因为我没有完全理解控制和事件而对我投了反对票?身份证。但是我还有一个问题,我可以在这些 cmets 中问你吗?让一个事件触发另一个事件是不好的做法吗?就像组合框上的 customindexchanged 事件触发事件以更改标签。
  • 有时我发现自己在这样做,但我通常会更正它并按应有的方式编写代码。这是规则:控制事件不应包含任何冗长的代码。相反,他们应该调用一个函数(有一个好听的名字)来完成这项工作。
  • 示例:SaveButton 不应该进行保存。它应该调用 saveData 函数。 SaveDataMenuItem 应该调用相同的函数,而不是 saveButtonClick!当您想要更改 GUI 并取消 OkButton 时,无需更改代码。在更广泛的背景下,这是视图和模型的分离;所以:是的,这是一种不好的做法,但有时会陷入其中。
猜你喜欢
  • 2015-09-10
  • 2021-08-31
  • 1970-01-01
  • 2020-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-08
  • 1970-01-01
相关资源
最近更新 更多