首页 > 解决方案 > 检查以避免在 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);
                }
            }

我试过了,现在我什至无法在画布上添加形状。我根本看不出我做错了什么。

标签: c#wpfcanvas

解决方案


您的Draw()方法将vorm类型添加Shape到指定的画布中canvas。我假设你的sm.maakEllips()回报是一个椭圆。

因此,当您运行以下代码时:

Shape shape = sm.maakEllips();
if (!canvas.Children.Contains(shape))
{
    cm.Draw(shape, canvas, locatie);
}

只有当画布包含您在上面一行中使用方法创建的确切对象时,您才会进入if语句内部。它不能是与上述对象具有相同属性的任何形状。因为,每次您创建一个新对象时,即使具有完全相同的属性(包括其名称),它们仍然是世界上两个不同的对象。shapesm.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并将其添加到myCanvasusingDraw()方法时,它成为myCanvas.Children.
  • 然后,当您使用 来检查它是否是if (!myCanvas.Children.Contains(sh1))子元素时,由于那时它是子元素,因此条件变为false并且我们不进入if子句。
  • 接下来,我们创建sh2,它具有与 完全相同的尺寸和名称sh1。但是,这是关键,.NET即使它与前一个对象具有相同的属性,也将其视为不同的对象。原因是,每当我们使用new关键字时,.NET都会创建一个实际的新对象。
  • 之后,我们不使用Draw()方法将它添加到画布中。
  • 现在,if当我们第二次检查是否myCanvas包含对象时,它发现它sh2不是 的孩子myCanvas,所以它进入if子句。

推荐阅读