行。删除所有代码并重新开始。
这就是你在 WPF 中做数独板的方式:
XAML:
<Window x:Class="WpfApplication4.Window17"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window17" Height="300" Width="300">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="9" Columns="9"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Row" Value="{Binding Row}"/>
<Setter Property="Grid.Column" Value="{Binding Column}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Value}" VerticalAlignment="Stretch" FontSize="20" TextAlignment="Center"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
代码背后:
using System.Collections.Generic;
using System.Windows;
using System.ComponentModel;
namespace WpfApplication4
{
public partial class Window17 : Window
{
public Window17()
{
InitializeComponent();
var random = new Random();
var board = new List<SudokuViewModel>();
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
board.Add(new SudokuViewModel() {Row = i, Column = j,Value = random.Next(1,20)});
}
}
DataContext = board;
}
}
}
视图模型:
public class SudokuViewModel:INotifyPropertyChanged
{
public int Row { get; set; }
public int Column { get; set; }
private int _value;
public int Value
{
get { return _value; }
set
{
_value = value;
NotifyPropertyChange("Value");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChange(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
如您所见,我绝不会在代码中创建或操作 UI 元素。这在 WPF 中是完全错误的。您必须学习 MVVM,并了解UI 不是数据。数据就是数据。界面就是界面
现在,每当您需要对 TextBoxes 中的 Value 进行操作时,只需对public int Value
ViewModel 中的属性进行操作即可。您的应用程序逻辑和 UI 必须完全解耦。
只需将我的代码复制并粘贴到 a 中File -> New Project -> WPF Application
,然后自己查看结果。这是它在我的电脑中的样子:
编辑:
我已修改示例以在更改值时调用方法。
请理解,您不应针对 WPF 中的 UI 进行操作,而应针对 DATA。你真正关心的是数据(ViewModel),而不是 UI 本身。
using System.Collections.Generic;
using System.Windows;
using System.ComponentModel;
using System;
namespace WpfApplication4
{
public partial class Window17 : Window
{
public List<SudokuViewModel> Board { get; set; }
public Window17()
{
InitializeComponent();
var random = new Random();
Board = new List<SudokuViewModel>();
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
Board.Add(new SudokuViewModel()
{
Row = i, Column = j,
Value = random.Next(1,20),
OnValueChanged = OnItemValueChanged
});
}
}
DataContext = Board;
}
private void OnItemValueChanged(SudokuViewModel vm)
{
MessageBox.Show("Value Changed!\n" + "Row: " + vm.Row + "\nColumn: " + vm.Column + "\nValue: " + vm.Value);
}
}
public class SudokuViewModel:INotifyPropertyChanged
{
public int Row { get; set; }
public int Column { get; set; }
private int _value;
public int Value
{
get { return _value; }
set
{
_value = value;
NotifyPropertyChange("Value");
if (OnValueChanged != null)
OnValueChanged(this);
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChange(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public Action<SudokuViewModel> OnValueChanged { get; set; }
}
}