【问题标题】:Relocate children in grid在网格中重新定位孩子
【发布时间】:2017-04-30 20:43:45
【问题描述】:

我正在尝试使用 WPF 在 C# 中实现一个国际象棋游戏。到目前为止,我已经可视化了国际象棋网格和其中的数字。我的 .xaml 文件只包含一个 8x8 的网格(名为“playground”)。 .xaml.cs 文件中的初始化如下所示:

for (int x = 0; x < 8; x++)
{
    for (int y = 0; y < 8; y++)
    {
        Border border = new Border();

        if (y % 2 == (x % 2 == 0 ? 0 : 1))
        {   // Chess like look
            border.Background = black; //black is a static SolidColorBrush
        }

        // a ChessTile is an Image which can be a Figure or an EmptyTile
        // omitted code... evaluate whether what figure the tile is or empty
        ChessTile tile;

        Grid.SetColumn(border, x);
        Grid.SetRow(border, y);

        border.HorizontalAlignment = HorizontalAlignment.Stretch;
        border.VerticalAlignment = VerticalAlignment.Stretch;

        if (tile is Figure)
        {
            // Set Event to border so the user is able to click outside the image
            border.MouseDown += ClickFigure; 
        }

        border.Child = tile; // Set tile as Child
        playground.Children.Add(border); // Add border to Child
    }
}

初始化后,我想将国际象棋图形移动到网格中的另一列和/或行。目前,我正在 ClickFigure 中评估该图能够移动到哪个空图块,然后向这些空图块添加一个新的处理程序并将我的图移到那里。我在处理程序中调用 tile.Move(otherTile):
(来自 ChessTile.cs)

public Vector Coordinates
{
    get
    {
        return position; //private Vector
    }
    private set
    {
        position = value;
        Grid.SetRow(this, (int)position.X); //relocate this (ChessTile)
        Grid.SetColumn(this, (int)position.Y);
    }
}

public void Move(ChessTile other)
{
    Vector temp = position;
    Coordinates = other.position; //relocating both tiles through properties
    other.Coordinates = temp;
}

现在的问题是网格根本没有做任何事情。我搜索了一些手动更新/重新绘制网格的方法,但我没有找到任何东西。我还尝试先删除孩子,然后再次添加它,但这给了我一个错误,说孩子已经绑定到UIElement,我必须先将它分开。
你知道我做错了什么吗?

【问题讨论】:

  • 即使有,但特别是没有,一个好的minimal reproducible example,你的问题太宽泛了。我会建议:not 在代码隐藏中创建 UI 对象。 在表示游戏棋子和棋盘位置的两种不同模型数据结构(例如“视图模型”)中严格管理您的游戏状态。棋子模型将具有棋盘位置和选择状态的属性。
  • 板位置将具有基于例如启用的单击命令第一次单击(选择棋子)和第二次单击(选择目的地),其中命令的启用状态受到相应控制(即在第一次单击之前,如果棋子在该位置则启用,在第一次单击之后但在第二次单击之前,为位置启用对所选棋子有效)。
  • 如果 UIElement 在网格中,您只需更改该元素的 Grid.Row / Grid.Column。我不确定可能出了什么问题,但就是这么简单。
  • 至少,您需要研究:MVVM、ICommand 和数据模板。毫无疑问,在您看来,这比仅仅修复您现在拥有的代码要麻烦很多。但我向您保证,从长远来看,它将显着提高您编写 WPF 代码的效率。
  • @MichaelPuckettII:当然这与在网格中移动项目有关。 OP 无法调试他的代码的最大原因是他将他的 UI 与他的非 UI 混合在一起。

标签: c# wpf windows xaml


【解决方案1】:

你需要改变原来Border上的行和列放在Grid里面。

在您的设置代码中,您在边框对象上设置列和行:

Grid.SetColumn(border, x);
Grid.SetRow(border, y);

但是在您的Coordinates 属性中,您将在this 上设置列和行。

Grid.SetRow(this, (int)position.X); //relocate this (ChessTile)
Grid.SetColumn(this, (int)position.Y);

假设this 是您编写的自定义类,那么您需要确保它具有对原始Border 的引用并将您的Coordinate 设置器更改为:

Grid.SetRow(border, (int)position.X); //relocate the border!
Grid.SetColumn(border, (int)position.Y);

注意 this => border 的变化。

【讨论】:

    猜你喜欢
    • 2020-05-08
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 2020-03-22
    • 2021-09-10
    相关资源
    最近更新 更多