c# - 检查以避免在 WPF/C# 中向画布添加多个项目
问题描述
Shape shape = sm.maakEllips();
if (!canvas.Children.Contains(shape))
{
cm.Draw(shape, canvas, locatie);
}
public void Draw(Shape vorm, Canvas canvas, Point locatie)
{
if (vorm.Height <= canvas.Height && vorm.Width <= canvas.Width)
{
Canvas.SetTop(vorm, locatie.Y);
Canvas.SetLeft(vorm, locatie.X);
canvas.Children.Add(vorm);
}
}
所以我在 Draw() 中为画布添加了一个形状。然后,当我在上面的 if 子句中检查这一点时,我仍然可以多次将相同的形状添加到同一个画布上。我不明白,我做错了什么?
编辑:
Shape shape = sm.makeShape(Convert.ToByte(textboxR.Text), Convert.ToByte(textboxG.Text), Convert.ToByte(textboxB.Text), Convert.ToInt32(textboxHoogte.Text), Convert.ToInt32(textboxBreedte.Text));
foreach (Shape existingShape in canvas.Children.OfType<Shape>())
{
if (existingShape.Width != shape.Width && existingShape.Height != shape.Height
&& existingShape.Fill != shape.Fill)
{
cm.Draw(shape, canvas, locatie);
}
}
我试过了,现在我什至无法在画布上添加形状。我根本看不出我做错了什么。
解决方案
您的Draw()
方法将vorm
类型添加Shape
到指定的画布中canvas
。我假设你的sm.maakEllips()
回报是一个椭圆。
因此,当您运行以下代码时:
Shape shape = sm.maakEllips();
if (!canvas.Children.Contains(shape))
{
cm.Draw(shape, canvas, locatie);
}
只有当画布包含您在上面一行中使用方法创建的确切对象时,您才会进入if
语句内部。它不能是与上述对象具有相同属性的任何形状。因为,每次您创建一个新对象时,即使具有完全相同的属性(包括其名称),它们仍然是世界上两个不同的对象。shape
sm.maakEllips()
shape
.NET
为了说明这一点,请参见下面的代码示例。
您未更改的Draw()
方法:
public void Draw(Shape vorm, Canvas canvas, Point locatie)
{
if (vorm.Height <= canvas.Height && vorm.Width <= canvas.Width)
{
Canvas.SetTop(vorm, locatie.Y);
Canvas.SetLeft(vorm, locatie.X);
canvas.Children.Add(vorm);
}
}
一种makeEllipse()
方法,它创建一个宽度和高度分别为 100 和 80 的椭圆,并分配name
传入的参数。
public Shape makeEllipse(string name)
{
Shape sh = new Ellipse
{
Name = name,
Width = 100,
Height = 80,
};
return sh;
}
现在查看以下代码,单击按钮即可执行。
private void btnGO_Click(object sender, RoutedEventArgs e)
{
// Creates an ellipse with name "Shape1", and assigns to sh1.
Shape sh1 = makeEllipse("Shape1");
// Adds the said sh1 to the canvas using `Draw()` method.
Draw(sh1, myCanvas, new Point(5, 5));
// See if sh1 exists as a child of `myCanvas`.
// Since sh1 is now a child of canvas, code does NOT go inside the if-clause.
if (!myCanvas.Children.Contains(sh1))
{
Draw(sh1, myCanvas, new Point(5, 5));
}
// Creates an ellipse with the same name "Shape1", and assigns to sh2.
Shape sh2 = makeEllipse("Shape1");
// It is NOT added to the canvas using `Draw()` method.
// Now, here, code DOES go inside the if-clause, because the said object does not exist as a child of `myCanvas`.
if (!myCanvas.Children.Contains(sh2))
{
Draw(sh2, myCanvas, new Point(5, 5));
}
}
上面的评论应该已经足够好了,但再次解释一下,
- 当您创建
sh1
并将其添加到myCanvas
usingDraw()
方法时,它成为myCanvas.Children
. - 然后,当您使用 来检查它是否是
if (!myCanvas.Children.Contains(sh1))
子元素时,由于那时它是子元素,因此条件变为false
并且我们不进入if
子句。 - 接下来,我们创建
sh2
,它具有与 完全相同的尺寸和名称sh1
。但是,这是关键,.NET
即使它与前一个对象具有相同的属性,也将其视为不同的对象。原因是,每当我们使用new
关键字时,.NET
都会创建一个实际的新对象。 - 之后,我们不使用
Draw()
方法将它添加到画布中。 - 现在,
if
当我们第二次检查是否myCanvas
包含对象时,它发现它sh2
不是 的孩子myCanvas
,所以它进入if
子句。
推荐阅读
- php - php - 仅计算子文件夹级别的文件,每个文件夹的回显总数
- javascript - 使用带有 express 和 ejs 的套接字 io
- java - rest api xml 使用错误 com.fasterxml.jackson.core.JsonParseException:序言中的意外字符'"'(代码 34);预期'<'
- c++ - 在列表中插入值
- regex - Vim 替代 - 用括号括起来 `\ref{eq:x}`
- javascript - 如果对象的属性包含任何子字符串,则从数组中减少对象
- c - 如何使用 C 在运行时更改串行端口的波特率?
- javascript - 如何使用下拉列表中的值向数据库发送请求?
- c# - 访问克隆选项卡项中的控件
- java - 以分钟、秒、毫秒等形式确定瞬间的精度?