我用 C#、XAML 和 MVVM-Light 构建了一个非常基本的数独应用程序。 MainWindow 每个单元格有一个 9x9 网格和 81 个文本框,MainViewModel 有 81 个 int 属性。不漂亮。数独表格看起来不像经典表格,没有“较粗的边框”来区分每个象限。
现在,我想进入下一个阶段,让它变得漂亮又实用。
每个单元格内容都必须是“响应式”的?即根据窗口的宽度/高度调整大小(字体大小)。我已经开始研究处理字体颜色、背景颜色等的 CellUserControl。
主窗口的基础应该是什么?网格、表格、列表框、自定义?
- 我尝试过网格和表格,但通常都会陷入死胡同。 XAML 变得非常冗长且重复。
- 我记得 MS 展示了 WPF 的强大功能,只需应用样式即可将 ListBox 显示为轮播。这是有效路径吗?
- 自定义控件:它是否太过分了,或者它的存在正是为了这种情况?
顺便说一句,我将大量利用 MVVM-Light 和数据绑定(bind)。
最佳答案
由于所有单元格应具有相同的大小,因此您也可以使用 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
。边框的厚度是根据当前单元格的位置确定的。这将为您提供典型的数独表格外观。
文本框数据绑定(bind)到 View 模型的二维索引器属性。这是 View 模型:
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);
}
}
此索引器返回一个字符串,但您可能希望将其更改为整数并执行适当的转换和错误检查。无论如何,当索引器属性更新时,它都会使用 MVVM Light 引发 PropertyChanged
事件。
我在这里使用我的解决方案创建了一个存储库:https://github.com/redcurry/Sudoku .
关于c# - WPF 中的数独 - 我应该为表格使用什么基本元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54055388/