You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WinForm构建带草稿功能数独面板的实现方案咨询

WinForm数独游戏面板优化实现方案

现有代码存在的问题

  • 控件创建逻辑冗余:内层a、b循环无实际作用,每次循环都重复给同一组小文本框赋值,最终仅生效最后一次创建的控件,且私有字段仅存储6个控件实例,后续无法定位对应单元格的草稿值
  • 位置计算不合理:小文本框位置基于窗体固定,未跟随主文本框绑定,调整主控件位置时所有小控件位置都要重新计算
  • 无输入限制:未给小文本框添加1-9的输入校验,不符合需求
  • 控件管理混乱:未按单元格分组,后续做数独校验、草稿清除等逻辑时无法快速定位对应控件

优化实现方案

1. 自定义用户控件封装单格逻辑

创建SudokuCellControl用户控件,将1个主文本框和5个草稿文本框的位置、输入校验、值存取逻辑封装在内,外层无需再单独管理两类控件,逻辑完全解耦:

// 自定义数独单元格控件
public partial class SudokuCellControl : UserControl
{
    // 暴露主数值属性,方便外层读写
    public int? MainValue 
    {
        get => int.TryParse(txtMain.Text, out int v) ? v : null;
        set => txtMain.Text = value?.ToString() ?? string.Empty;
    }
    // 暴露草稿值数组,对应5个草稿位的数值
    public int?[] DraftValues { get; } = new int?[5];
    private TextBox txtMain;

    public SudokuCellControl()
    {
        Size = new Size(40,40);
        // 初始化主文本框
        txtMain = new TextBox()
        {
            Multiline = true,
            Font = new Font("微软雅黑", 16f, FontStyle.Bold),
            TextAlign = HorizontalAlignment.Center,
            Dock = DockStyle.Fill,
            BorderStyle = BorderStyle.None,
            BackColor = Color.White
        };
        Controls.Add(txtMain);
        // 5个草稿框的对应位置:左上、右上、左下、右下、中间
        Point[] draftPositions = new Point[]
        {
            new Point(2,2), new Point(Width - 23,2), 
            new Point(2, Height - 23), new Point(Width -23, Height -23),
            new Point(Width/2 - 10, Height/2 -10)
        };
        for(int i=0; i<5; i++)
        {
            var txtDraft = new TextBox()
            {
                Size = new Size(21,20),
                Location = draftPositions[i],
                BorderStyle = BorderStyle.None,
                Font = new Font("微软雅黑", 8f),
                TextAlign = HorizontalAlignment.Center,
                Tag = i // 标记当前是第几个草稿位
            };
            // 限制草稿框仅允许输入1-9
            txtDraft.KeyPress += (s,e) =>
            {
                if (!char.IsDigit(e.KeyChar) && e.KeyChar != (char)Keys.Back)
                {
                    e.Handled = true;
                    return;
                }
                if (char.IsDigit(e.KeyChar) && (e.KeyChar < '1' || e.KeyChar > '9'))
                    e.Handled = true;
            };
            txtDraft.TextChanged += (s,e) =>
            {
                var sender = s as TextBox;
                int index = (int)sender.Tag;
                DraftValues[index] = int.TryParse(sender.Text, out int v) ? v : null;
            };
            Controls.Add(txtDraft);
            txtDraft.BringToFront();
        }
        // 主文本框输入后自动清空当前单元格所有草稿
        txtMain.TextChanged += (s,e) =>
        {
            if(MainValue.HasValue)
            {
                foreach (Control c in Controls)
                {
                    if (c is TextBox txt && txt != txtMain) txt.Text = string.Empty;
                }
            }
        };
    }
}

2. 外层窗体布局优化

外层用TableLayoutPanel布局81个自定义单元格控件,位置自动计算,同时用二维数组存储所有单元格实例,方便后续数独逻辑校验:

public partial class MainForm : Form
{
    // 存储所有单元格,按[row,col]索引定位
    private SudokuCellControl[,] _allCells = new SudokuCellControl[9,9];
    private void MainForm_Load(object sender, EventArgs e)
    {
        var tableLayout = new TableLayoutPanel()
        {
            RowCount =9,
            ColumnCount =9,
            Dock = DockStyle.Fill,
            CellBorderStyle = TableLayoutPanelCellBorderStyle.Single,
            Padding = new Padding(20)
        };
        for(int row=0; row<9; row++)
        {
            tableLayout.RowStyles.Add(new RowStyle(SizeType.Percent, 100f/9));
            for(int col=0; col<9; col++)
            {
                if(row == 0) tableLayout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f/9));
                var cell = new SudokuCellControl()
                {
                    Dock = DockStyle.Fill,
                    Tag = new Point(row,col)
                };
                // 给3*3九宫格块设置间隔背景色方便区分
                if ((row/3 + col/3) %2 ==0) cell.BackColor = Color.LightGray;
                _allCells[row, col] = cell;
                tableLayout.Controls.Add(cell, col, row);
            }
        }
        Controls.Add(tableLayout);
    }
}

3. 额外优化建议

如果追求更高性能,可以不用创建小文本框,直接重写OnPaint方法在主控件上绘制草稿数字,能减少400+控件实例,运行效率更高。


内容的提问来源于stack exchange,提问作者Pro Ismael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 16:15:03