拉风的咖菲猫
由于所有单元格都应具有相同的大小,因此您也可以使用UniformGrid。正如 Leo Bartkus 建议的那样,您可以使用代码隐藏来生成单元格和文本框。为此,首先在 XAML 中为数独表创建一个占位符:<!-- Placeholder for Sudoku table (filled in code-behind) --><Border x:Name="SudokuTable" />假设您使用的是Window,这是代码隐藏:public partial class MainWindow : Window{ private const int InnerWidth = 3; private const int OuterWidth = InnerWidth * InnerWidth; private const int Thin = 1; private const int Thick = 3; public MainWindow() { InitializeComponent(); InitializeViewModel(); InitializeSudokuTable(); } public SudokuViewModel ViewModel => (SudokuViewModel)DataContext; private void InitializeViewModel() { DataContext = new SudokuViewModel(OuterWidth); } private void InitializeSudokuTable() { var grid = new UniformGrid { Rows = OuterWidth, Columns = OuterWidth }; for (var i = 0; i < OuterWidth; i++) { for (var j = 0; j < OuterWidth; j++) { var border = CreateBorder(i, j); border.Child = CreateTextBox(i, j); grid.Children.Add(border); } } SudokuTable.Child = grid; } private static Border CreateBorder(int i, int j) { var left = j % InnerWidth == 0 ? Thick : Thin; var top = i % InnerWidth == 0 ? Thick : Thin; var right = j == OuterWidth - 1 ? Thick : 0; var bottom = i == OuterWidth - 1 ? Thick : 0; return new Border { BorderThickness = new Thickness(left, top, right, bottom), BorderBrush = Brushes.Black }; } private TextBox CreateTextBox(int i, int j) { var textBox = new TextBox { VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; var binding = new Binding { Source = ViewModel, Path = new PropertyPath($"[{i},{j}]"), Mode = BindingMode.TwoWay }; textBox.SetBinding(TextBox.TextProperty, binding); return textBox; }}嵌套循环为 81 个单元创建每个Border和TextBox。边框的粗细是根据当前单元格的位置确定的。这将为您提供典型的数独表外观。文本框数据绑定到视图模型的二维索引器属性。这是视图模型:public class SudokuViewModel : ViewModelBase{ private readonly string[,] _values; public SudokuViewModel(int width) { _values = new string[width, width]; } public string this[int i, int j] { get => _values[i, j]; set => Set(ref _values[i, j], value); }}此索引器返回一个字符串,但您可能希望将其更改为整数并进行适当的转换和错误检查。PropertyChanged在任何情况下,它都使用 MVVM Light在索引器属性更新时引发事件。我在这里用我的解决方案创建了一个存储库:https ://github.com/redcurry/Sudoku 。