【问题标题】:Location on winforms panel is not accuratewinforms 面板上的位置不准确
【发布时间】:2021-03-29 09:18:31
【问题描述】:

我一直在使用 C# 并使用 Visual Studio 2019 版本制作 WinForms 应用程序,并且在我的代码中遇到坐标系准确性问题。我有一些图形元素(实际上是标签),您可以单击一个并单击另一个位置,它将被移动到该位置,当我只是在应用程序的背景上执行此操作时,这相当准确。但是当我在图形元素后面添加一个面板时,它无法正常工作,而是将标签向上移动了一点。我通过在面板上画一些线条来说明这一点。这是我在面板内单击时的代码(称为绑定器):

private void Bonder_Click(object sender, MouseEventArgs e)
        {
            mousePosInBonder = e.Location;

            foreach (GraphicalElement el in elementsInBonder)
            {
                if (el.Dragging)
                {
                    while (el.Dragging)
                    {
                        if (!(mousePos.X > el.Location.X && mousePos.X < el.Location.X + el.Size.Width && mousePos.Y > el.Location.Y && mousePos.Y < el.Location.Y + el.Size.Height))
                        {
                            el.Location = mousePosInBonder;
                            el.Dragging = false;
                        }
                    }
                    break;
                }
            }
        }

这是我绘制线条(和点击)的代码:

private void GraphicalElement_Drag(object sender, MouseEventArgs e)
        {
            GraphicalElement el = (GraphicalElement)sender;

            if (e.Button == MouseButtons.Left)
            {
                if (el.Dragging)
                {
                    el.Dragging = false;
                }
                else if (!el.Dragging)
                {
                    el.Dragging = true;
                }
            }
            else if (e.Button == MouseButtons.Right)
            {
                if (el.Bonding)
                {
                    if (BONDING_ELEMENTS)
                    {
                        g = Bonder.CreateGraphics();
                        g.DrawLine(bonder, el.Location, LAST_BONDED_ELEMENT.Location);
                        BONDING_ELEMENTS = false;
                    }
                    else if (!BONDING_ELEMENTS)
                    {
                        LAST_BONDED_ELEMENT = el;
                        BONDING_ELEMENTS = true;
                    }
                }
            }
        }

当元素被点击时调用(因为标签不能被拖动)。 这是显示元素的 GraphicalElement 类的代码。

public partial class GraphicalElement:Label
    {
        // Attributes
        private bool dragging = false;
        private bool bonding = false;
        private string info = "";

        public GraphicalElement() { }

        public GraphicalElement(Element el)
        {
            Tag = el.ToString();
            Text = el.ChemicalFormula;
            AutoSize = true;
            Location = new Point(100, 100);
            
            info = el.Info;

            if (el.Type == "alkali metal")
            {
                BackColor = Color.Crimson;
            }
            else if (el.Type == "alkaline earth")
            {
                BackColor = Color.DarkOrange;
            }
            else if (el.Type == "transition metal")
            {
                BackColor = Color.Yellow;
            }
            else if (el.Type == "basic metal")
            {
                BackColor = Color.Green;
            }
            else if (el.Type == "semimetal")
            {
                BackColor = Color.Cyan;
            }
            else if (el.Type == "nonmetal")
            {
                BackColor = Color.Blue;
            }
            else if (el.Type == "halogen")
            {
                BackColor = Color.Pink;
            }
            else if (el.Type == "noble gas")
            {
                BackColor = Color.DarkMagenta;
            }
            else if (el.Type == "lathanide")
            {
                BackColor = Color.HotPink;
            }
            else if (el.Type == "actinide")
            {
                BackColor = Color.Maroon;
            }
        }

        // Getters and setters
        public bool Dragging
        {
            get { return dragging; }
            set { dragging = value; }
        }
        public bool Bonding
        {
            get { return bonding; }
            set { bonding = value; }
        }
        public string Info
        {
            get { return info; }
            set { info = value; }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
        }

    }

这是它的样子:

我该如何解决这个问题,因为它非常具有误导性。

编辑 这是将元素添加到 elementsInBonder 的位置:

private void GraphicalElement_Bond(object sender, MouseEventArgs e)
        {
            GraphicalElement el = (GraphicalElement)sender;
            
            if (el.Bonding)
            {
                elementsInBonder.Remove(el);
                elementsOnScreen.Add(el);
                el.Location = new Point(1011, 43);
                el.BringToFront();
                el.Bonding = false;
            }
            else if (!el.Bonding && BONDER_ON)
            {
                elementsOnScreen.Remove(el);
                elementsInBonder.Add(el);
                el.Location = new Point(12, 43);
                el.BringToFront();
                el.Bonding = true;
            }
        }

双击事件发生。

这就是我一开始就指定它的方式。 List&lt;GraphicalElement&gt; elementsInBonder;。 GraphicalElement 不是 Panel 的子元素,因为 Graphical Elements 可以通过在两个列表之间跳转来移入和移出 Bonder 面板:elementsOnScreen 也是如此。

【问题讨论】:

  • 因为在 MouseEventArgs 中传递的坐标是相对于容器的?但是我看不到点击事件如何接收鼠标坐标。
  • 什么是mousePos? -- 你不应该使用Bonder.CreateGraphics();,你应该在Panel的Paint事件中画线。
  • @Jimi mousePos 是鼠标的位置。这是一个点。我试图使用Bonder.CreateGraphics,因为我试图确保用户只能在元素位于面板中时绑定元素。另外,我想知道,您提到了 Paint 事件。是否可以从另一个方法调用 Paint 事件,因为我认为这是一个事件。
  • 变量/字段未在任何地方定义,控件定位是问题所在。 -- 您的标签似乎是面板 (foreach (GraphicalElement el in elementsInBonder)) 的子标签,但您应该展示如何添加它们,因为 elementsInBonder(除其他外)未定义(为什么您没有 foreach (var el in Bonder.Controls.OfType&lt;GraphicalElement&gt;().ToList())? )。 -- Bonder.CreateGraphics() 完全错误。

标签: c# winforms graphics


【解决方案1】:

我主要通过反复试验找到了答案。面板稍微偏离左上角,所以我想知道 GraphicalElements 的偏离量是否与面板的偏离量相同,在这种情况下,右侧为 12 像素,向下为 43 像素。因此,我更改了代码来表示它。

对于 Bonder_click() 方法,我更改了 mousePosInBonder 以将其表示为如下几个像素:

private void Bonder_Click(object sender, MouseEventArgs e)
        {
            mousePosInBonder = new Point(e.Location.X+12, e.Location.Y+43);

            foreach (GraphicalElement el in elementsInBonder)
            {
                if (el.Dragging)
                {
                    while (el.Dragging)
                    {
                        if (!(mousePos.X > el.Location.X && mousePos.X < el.Location.X + el.Size.Width && mousePos.Y > el.Location.Y && mousePos.Y < el.Location.Y + el.Size.Height))
                        {
                            el.Location = mousePosInBonder;
                            el.Dragging = false;
                        }
                    }
                    break;
                }
            }
        }
    }

我更改的行是mousePosInBonder = new Point(e.Location.X+12, e.Location.Y+43);,而之前是mousePosInBonder = e.Location;

对于线条画,我做了类似的事情:

private void GraphicalElement_Drag(object sender, MouseEventArgs e)
        {
            GraphicalElement el = (GraphicalElement)sender;

            if (e.Button == MouseButtons.Left)
            {
                if (el.Dragging)
                {
                    el.Dragging = false;
                }
                else if (!el.Dragging)
                {
                    el.Dragging = true;
                }
            }
            else if (e.Button == MouseButtons.Right)
            {
                if (el.Bonding)
                {
                    if (BONDING_ELEMENTS)
                    {
                        g = Bonder.CreateGraphics();
                        g.DrawLine(convalentBonder, new Point(el.Location.X-12, el.Location.Y-43), new Point(LAST_BONDED_ELEMENT.Location.X-12, LAST_BONDED_ELEMENT.Location.Y-43));
                        BONDING_ELEMENTS = false;
                    }
                    else if (!BONDING_ELEMENTS)
                    {
                        LAST_BONDED_ELEMENT = el;
                        BONDING_ELEMENTS = true;
                    }
                }
            }
        }

在这里,我更改的行是g.DrawLine(convalentBonder, new Point(el.Location.X-12, el.Location.Y-43), new Point(LAST_BONDED_ELEMENT.Location.X-12, LAST_BONDED_ELEMENT.Location.Y-43));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-19
    • 2021-09-04
    • 2020-06-10
    • 1970-01-01
    • 2017-03-29
    • 2021-03-03
    • 2021-03-21
    • 1970-01-01
    相关资源
    最近更新 更多