Search code examples
c#wpfcanvaselementargumentnullexception

Why I can't remove image in canvas WPF C#?


I have my class in Anobject.cs file:

public class AnObject
{
    public string Name { get; set; }
    public int? X { get; set; }
    public int? Y { get; set; }
    public AnObject(string name = null, int? x = null, int? y = null)
    {
        this.Name = name;
        this.X = x;
        this.Y = y;
    }
}

And my page RolePlay.xaml.cs:

readonly AnObject[,] allObjects = new AnObject[50,38];
    private void RolePlayPage_Loaded(object sender, RoutedEventArgs e)
    {
        AnObject anObject = new AnObject();
        for (int i = 0; i < 50; i++)
        {
            for (int j = 0; j < 38; j++)
            {
                allObjects[i, j] = anObject;
            }
        }

        List<string> lines = File.ReadAllLines(@"myfile.txt").ToList();
        foreach (string line in lines)
        {
            string[] data = line.Split(' ');
            string data0 = data[0];
            int data1 = int.Parse(data[1]);
            int data2 = int.Parse(data[2]);

            anObject = new AnObject(data0, data1, data2);

            allObjects[data1, data2] = anObject;
        }
    }

My creating image in canvas method:

    private void UpdateAllObjects()
    {
        foreach (AnObject obj in allObjects)
        {
            if (obj.Name != null)
            {
                Image objPic = new Image
                {
                    Name = obj.Name + obj.X.ToString() + obj.Y.ToString(),
                    Width = 20,
                    Height = 20,
                    Source = new BitmapImage(new Uri($@"Objects\{obj.Name}.png", UriKind.Relative))
                };
                Canvas.SetLeft(objPic, (double)(obj.X * 20));
                Canvas.SetTop(objPic, (double)(obj.Y * 20));
                RolePlayCanvas.Children.Add(objPic);
            }
        }
    }

My problems are here in my removePic method:

if (allObjects[x, y].Name != null)
{
    Image picName = (Image)FindName(allObjects[x, y].Name + allObjects[x, y].X.ToString() + allObjects[x, y].Y.ToString());
    RolePlayCanvas.Children.Remove(picName);
    // Canvas.SetLeft(picName, 0);
    allObjects[x, y].Name = null;
}

why the picName isn't removed from canvas? Try to excutes this "Canvas.SetLeft(picName, 0);" line will occur error: System.ArgumentNullException: 'Value cannot be null'.


Solution

  • Your lookup probably fails. Try to debug this code to determine whether element is actually set to an Image element to be removed:

    var obj = allObjects[x, y];
    if (obj != null)
    {
        var name = obj.Name + obj.X.ToString() + obj.Y.ToString();
        var element = RolePlayCanvas.Children.OfType<Image>().FirstOrDefault(x => x.Name == name);
        if (element != null)
            RolePlayCanvas.Children.Remove(element);
    }