【问题标题】:Data binding to a nested property with possibly null parent数据绑定到可能为 null 父级的嵌套属性
【发布时间】:2018-07-27 20:14:04
【问题描述】:

我想对Room.ToNorth.ImageName 执行数据绑定,而ToNorth 可能为空。

我正在尝试编写自己的文字冒险,并在玩家可以去的每个方向(即打开/关闭的门、路径)旁边放置图像。当给定方向上没有房间时,我将控件绑定为显示“无退出”图像,只要玩家起始位置在所有 4 个方向上都有一个出口,这很有效,但是当一个为空时,我得到以下异常

System.ArgumentNullException: '值不能为空。参数名称: 组件'

这不是新游戏的问题,但我正在制作随机生成的地牢,因此无法保证在加载游戏中。我意识到我可以通过在设置绑定时创建一个安全空间然后将玩家移动到他们需要的位置来伪造它,但是有没有适当的方法来处理这个问题?

我找到的最接近的答案是this question,但由于它的绑定方式,我不确定我是否可以在这里应用它。

private GameSession _CurrentGame;
private BindingSource _BindToPlayer = new BindingSource();

private void BtnNewGame_Click(object sender, EventArgs e)
{
    _CurrentGame = new GameSession();

    _BindToPlayer.DataSource = _CurrentGame.CurrentPlayer;

    PicBoxNorth.DataBindings.Add("ImageLocation", _BindToPlayer, 
        "CurrentRoom.ToNorth.ImageName", true, DataSourceUpdateMode.OnPropertyChanged, 
        "Images\\Wall.png");
}

ToNorth 属性只是从一个出口数组中获取对象,但是如果它为空(如上面链接中建议的那样)告诉它返回一个空出口会是有问题的,因为出口没有任何房间可以连接到并因此无法初始化可能会在此过程中引发异常。为了更好地解释,我的房间设置如下

public Class Room
{
   public int ID { get; set; }
    public String Name { get; set; }
    public String Description { get; set; }
    public String FarDescription { get; set; }
    public CoOrds Co_Ords { get; set; }

    public Boolean UniqueRoom { get; set; }

    public Exit[] ExitArr { get; set; }

    public Exit ToNorth => ExitArr[0];
    public Exit ToSouth => ExitArr[1];
    public Exit ToWest => ExitArr[2];
    public Exit ToEast => ExitArr[3];
    public Exit ToUp => ExitArr[4];
    public Exit ToDown => ExitArr[5];

    public Exit ToIn => ExitArr[6];
    public Exit ToOut => ExitArr[7];

    public Room(int id, String name, String desc, String fardesc,bool unique = false)
    {
        ID = id;
        Name = name;
        Description = desc;
        FarDescription = fardesc;
        Co_Ords = new CoOrds();
        ExitArr = new Exit[8];

        UniqueRoom = unique;

    }

我的出口是这样设置的

public class Exit
{
    public String Description {get;}         

    public Room RoomA { get; set; }
    public Room RoomB { get; set; }

    public Boolean CanExitA { get; set; } = true;
    public Boolean CanExitB { get; set; } = true;

    public Room NextRoom
    {
        get
        {

            if (RoomA.PlayerHere && CanExitA)
            { return RoomB; }
            else if (RoomB.PlayerHere && CanExitB)
            { return RoomA; }
            else
                return null;
        }
    }

    public String ImageName
    {
        get
        {
            string imagePath = "Images\\";
            if (DoorHere != null)
            {
                return imagePath + DoorHere.ImageName;
            }
            else
                return imagePath + "Pathway.png";
        }

    }

    public Door DoorHere { get; set; }

    public Exit(Room roomA, int Adir, Room roomB, int Bdir, Door door = null)
    {
        RoomA = roomA;
        RoomA.ExitArr[Adir] = this;
        RoomB = roomB;
        RoomB.ExitArr[Bdir] = this;
        DoorHere = door;

    }

Door 只是一个未命名的对象,带有一些用于 IsOpen、IsLocked 等的布尔值,如果您想对此进行测试,则不需要,但出口是匿名创建的,并将它们自己添加到两个连接房间的出口数组中,因此创建空的会失败。

任何建议将不胜感激。

【问题讨论】:

  • 您的实施中的示例代码将有很大帮助。您可以有一个空列表而不是 null。这可能会消除数据绑定问题。
  • 哪一行代码给了你这个异常?
  • 不用担心,Mightee 我认为我添加的内容就足够了,我已经更新了我的房间和出口的实施,所以你可以看到它们是如何连接的
  • 我得到的错误出现在 PicBoxNorth.DataBindings... 行。就像我说的那样,当那条线运行时那里有一些东西很好,以后不会被空值打扰(它显示 Wall.png)
  • 我会假设在这种情况下列表充满了空值,而不是空的,如果不是我将如何检查?

标签: c# .net winforms data-binding


【解决方案1】:

作为一种选择,您可以创建一个属性来进行空值检查并使用该属性获取/设置二级属性。

例如,在您的代码中,您可以创建ToNorthImageName 属性来获取/设置ToNorth.ImageNamein Room 类的值:

public string ToNorthImageName
{
    get { return ToNorth?.ImageName }
    //set { if (ToNorth != null) ToNorth.ImageName = value; }
}

属性设置器是可选的,如果你只想读取图像名称,可以将其删除。

然后设置数据绑定到该属性:

PicBoxNorth.DataBindings.Add("ImageLocation", _BindToPlayer, "ToNorthImageName",
    true, DataSourceUpdateMode.OnPropertyChanged);

【讨论】:

  • 我只是想在你编辑之前澄清你的意思,但这会起作用。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-20
  • 2012-07-19
  • 2012-12-14
  • 1970-01-01
  • 2023-03-13
相关资源
最近更新 更多