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
相关产品推荐
相关产品推荐

