当我在C# WPF中使用for循环创建按钮时,为什么按钮不在网格中显示?

iyfjxgzm  于 2023-01-27  发布在  C#
关注(0)|答案(1)|浏览(171)

尝试使用按钮为Connect 4游戏制作一个棋盘,但是在创建了一个方法来通过为网格中的每个单独的单元创建按钮来创建实际的棋盘本身之后,什么都没有显示。

public partial class MainWindow : Window
    {
        private readonly int[,] _board;
        private readonly int _height;
        private readonly bool _isComp;
        private readonly Brush _p1Color;
        private readonly string _p1Name;
        private readonly Ellipse _p1Sym;
        private readonly int _width;
        private readonly int _win;
        private Ellipse mycircle;
        private bool _isFalling;
        private bool turnPlayer1;
        private int _turns;
        private string _winner;
        public string Mode;
        public int[,] BoardArray = new int[5, 6];
            
        public MainWindow()
        {

        }

        public MainWindow (int row, int column , int win, Ellipse newP1, Ellipse newP2, Brush p1Color, Brush p2Color,
        string p1Name, string p2Name, bool isComp, int time, string mode, Brush back, Uri music)
        {
            InitializeComponent();
            turnPlayer1 = true;
            for (int loopColumn = 0; loopColumn <= 6; loopColumn++)
            {
                for (int loopRow = 0; loopRow <= 5; loopColumn++)
                {
                    BoardArray[loopRow, loopColumn] = 0;
                }
            }
            row = 6;
            column = 7;
            CreateBoard(column, row);
            mycircle  = newP1;
            _p1Color = p1Color;
            _p1Name = p1Name;
            _win = win;
            _winner = "";
            _isComp = isComp;
            Mode = mode;
        }

        private void buttonClicked(Button btn)
        {
            var rowDef = Grid.GetRow(btn);
            var columnDef = Grid.GetColumn(btn);
            var col = columnDef;
            DropCounter(col);
        }

        private int EmptyRow(int column)
        {
            for(int row = 6-1;row >=0;row-- )
            {
                var arrayRow = row; ;
                var arrayCol = column;
                if(BoardArray[row,column]== 0)
                {
                    return row;
                }
            }

            return -1;
        }
        private void DropCounter(int column)
        {
            var freeRow = EmptyRow(column);
            if (freeRow == -1) return;

            mycircle = new Ellipse();
            mycircle.Stroke = System.Windows.Media.Brushes.Black;
            mycircle.Fill = System.Windows.Media.Brushes.DarkBlue;
            mycircle.Height = 100;
            mycircle.Width = 100;
       
            Grid.SetColumn(mycircle, 1);
            Grid.SetRow(mycircle, 1);
            myGrid.Children.Insert(0,mycircle);
        }

        private void Btn_Click(object sender, RoutedEventArgs e)
        {
            if (sender is Button btn && EmptyRow(Grid.GetColumn(btn)) != -1) buttonClicked(btn);
        }

        private void CreateBoard(int column,int rows)
        {
            for (var row = 0; row < rows; row++)
            {
                for (var col = 0; col < column; column++)
                {
                    Button button = new Button();
                    {
                        var brush = new ImageBrush();
                        brush.ImageSource = new BitmapImage(new Uri("gridsingle.png.bmp", UriKind.Relative));
                        button.Background = brush;
                        Name = "btn_" + row + "_" + column;

                    };
                    button.Click += Btn_Click;
                    Grid.SetRow(button, row);
                    Grid.SetColumn(button, column);
                    myGrid.Children.Add(button);
                }
            }
        }

    }
}

抱歉代码太乱了,这是高中的硬件作业,编程不是我最喜欢的部分
不是很确定主要原因是什么,因为我正在实现与我的朋友相同的代码,但他的按钮都加载在他的窗口上。

cu6pst1q

cu6pst1q1#

老实说,这件事其实有很多问题。通常我会建议把它扔掉,重新开始,但我猜时间是一个因素,所以我会尽我所能帮助你。
首先,这看起来不对:

public MainWindow()
{
}

public MainWindow(int row, int column, int win, Ellipse newP1, Ellipse newP2, Brush p1Color, Brush p2Color, string p1Name, string p2Name, bool isComp, int time, string mode, Brush back, Uri music)
{

通常情况下,第一个构造函数是被调用的,因为你的实现是空的,这就解释了为什么你看不到任何东西。看看你的代码,传入第二个构造函数的参数实际上并没有被使用,所以去掉这两个构造函数,只保留初始化电路板所需的逻辑:

public MainWindow()
{
    InitializeComponent();
    turnPlayer1 = true;
    for (int loopColumn = 0; loopColumn <= 6; loopColumn++)
    {
        for (int loopRow = 0; loopRow <= 5; loopRow++)
        {
            BoardArray[loopRow, loopColumn] = 0;
        }
    }
    var row = 6;
    var column = 7;
    CreateBoard(column, row);
    _winner = "";
}

你会注意到在你的原始代码中有一个错误,我已经修复了:

for (int loopColumn = 0; loopColumn <= 6; loopColumn++)
{
    for (int loopRow = 0; loopRow <= 5; loopColumn++)

第二个循环应该递增loopRow,而不是loopColumn。(顺便提一下,您已经将这些循环硬编码为6列和5行,它们应该使用列和行变量中的值)。
接下来,CreateBoard函数中存在一个bug:

private void CreateBoard(int column, int rows)
{
    for (var row = 0; row < rows; row++)
    {
        for (var col = 0; col < column; column++)

column变量存储的是总列数,因此您应该执行col++,而不是column++。同样,当您设置按钮的Grid列时,您应该将其设置为col,而不是column:

button.Click += Btn_Click;
Grid.SetRow(button, row);
Grid.SetColumn(button, column);  // <---- this is wrong
myGrid.Children.Add(button);

DropCounter函数中的代码也有问题:

Grid.SetColumn(mycircle, 1);
Grid.SetRow(mycircle, 1);
myGrid.Children.Insert(0, mycircle);

注意,你总是把column和row设置为1,你应该把它们设置为column和freeRow。
最后,你永远不会更新BoardArray来记录令牌被丢弃的事实,所以你只会把它们放在最下面一行,你需要在DropCounter函数结束时更新它,这样你的EmptyRow函数才能正常工作:

BoardArray[freeRow, column] = 1;

相关问题