Как я могу получить положение текстового поля, которое было нажато?

Я пишу в WPF Sudoku Game, и я делаю во время выполнения 81 текстовое поле на canvasе:

public partial class Test : Window { private TextBox[,] texts = new TextBox[9, 9]; GameBoard board = new GameBoard(); public Test(string path) { InitializeComponent(); Initialization_text(); } void Initialization_text() { for (int i = 0; i < texts.GetLength(0); i++) { for (int j = 0; j < texts.GetLength(1); j++) { texts[i, j] = new TextBox(); texts[i, j].Name = "txt" + i + j; texts[i, j].Width = 40; texts[i, j].Height = 40; texts[i, j].MaxLength = 1; texts[i, j].FontSize = 22; texts[i, j].FontWeight = FontWeights.Bold; texts[i, j].Foreground = new SolidColorBrush(Colors.DimGray); texts[i,j].TextAlignment = TextAlignment.Center; Canvas.SetLeft(texts[i, j], (i+1)*40); Canvas.SetTop(texts[i, j], (j+1)*40); canvas1.Children.Add(texts[i, j]); } } } 

Мне нужно получить позицию текстового поля, в котором пользователь вводит номер для проверки значения, но я не могу написать метод, называемый TextBoxKeyDown, потому что его make во время выполнения

но если я напишу этот метод:

 private void canvas1_KeyDown(object sender, KeyEventArgs e) { if (sender.GetType().Name == "TextBox")//the sender is canvas { } } 

как я могу получить текстовое поле, в которое пользователь вводит номер? Помощь PLS …

ОК. Удалите весь свой код и начните все заново.

Так вы делаете доску Sudoku в WPF:

XAML:

                  

Код:

 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(); 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; } } } 

ViewModel:

  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)); } } 

Как вы можете видеть, Im никоим образом не создает или не манипулирует элементами пользовательского интерфейса в коде. Это просто неправильно в WPF. Вы должны изучить MVVM и понять, что пользовательский интерфейс - это не данные. Данные - это данные. Пользовательский интерфейс - это пользовательский интерфейс

Теперь, когда вам нужно действовать против значения в текстовых блоках, просто действуйте против public int Value свойства public int Value в ViewModel. Логика вашего приложения и ваш пользовательский интерфейс должны быть полностью развязаны.

Просто скопируйте и вставьте мой код в File -> New Project -> WPF Application и посмотрите результаты для себя. Так выглядит на моем компьютере:

введите описание изображения здесь

Редактировать:

Я изменил образец для вызова метода при изменении значения.

Пожалуйста, поймите, что вы не должны работать с пользовательским интерфейсом в WPF, а не с DATA. Что вам действительно нужно, так это DATA (ViewModel), а не сам пользовательский интерфейс.

 using System.Collections.Generic; using System.Windows; using System.ComponentModel; using System; namespace WpfApplication4 { public partial class Window17 : Window { public List Board { get; set; } public Window17() { InitializeComponent(); var random = new Random(); Board = new List(); 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 OnValueChanged { get; set; } } } 

Использовать подключенный обработчик событий

 AddHandler(TextBox.KeyDownEvent, new RoutedEventHandler(MyFieldClick)); 

это будет вызвано для каждого текстового поля внутри вызывающего элемента. Поэтому, если вы разместите это в своем окне, каждое текстовое поле KeyDownEvent будет обработано методом обработчика событий MyFieldClick. В этом случае отправителем является текстовое поле, которое первоначально отправило событие.

Но я aggree с HighCore, вы должны использовать WPF больше. В вашем случае я вижу ItemControls и сетку или лучше UniformGridPanel.

Btw TextChanged может быть более подходящим событием для вашего случая.

  • Индикатор выполнения с динамическим обновлением текста и текста
  • Пользовательский курсор в WPF?
  • Виртуализация элемента управления ItemsControl?
  • Как использовать фоновый рабочий стол WPF
  • Установите надстрочный индекс и индекс в форматированном тексте в wpf
  • WPF Combobox: различные шаблоны в текстовом поле и выпадающем списке
  • Шифрование учетных данных в приложении WPF
  • WPF: автозаполнение TextBox, ... снова
  • WPF MVVM Зачем использовать ContentControl + DataTemplate Views, а не прямые XAML Window Views?
  • WPF Как получить доступ к элементу управления из DataTemplate
  • Плоская кнопка wpf
  • Давайте будем гением компьютера.