【发布时间】: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<GraphicalElement> 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<GraphicalElement>().ToList())? )。 --Bonder.CreateGraphics()完全错误。