¿Cómo puedo obtener la posición del cuadro de texto que se ha presionado?

Estoy escribiendo en WPF el Sudoku Game y hago en tiempo de ejecución 81 cuadros de texto sobre 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]); } } } 

Necesito obtener la posición de la caja de texto que el usuario ingresa para verificar el valor, pero no puedo escribir el método que llamó a TextBoxKeyDown porque está en tiempo de ejecución

pero si escribo este método:

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

¿Cómo puedo obtener el cuadro de texto que ese usuario ingresa al número? los pls ayudan …

De acuerdo. Borre todo su código y comience de nuevo.

Así es como haces un tablero Sudoku en WPF:

XAML:

                  

Código detrás:

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

Como puede ver, de ninguna manera creo o manipulo elementos de UI en el código. Eso está completamente equivocado en WPF. Debe aprender MVVM y comprender que la IU no es información. Los datos son datos. UI es UI

Ahora, cada vez que necesite operar contra el valor en los cuadros de texto, simplemente opere contra la propiedad public int Value en ViewModel. Su lógica de aplicación y su UI deben estar completamente desacopladas.

Simplemente copie y pegue mi código en un File -> New Project -> WPF Application y vea los resultados usted mismo. Así es como se ve en mi computadora:

enter image description here

Editar:

Modifiqué la muestra para llamar a un método cuando se cambia un valor.

Por favor, comprenda que NO debe operar contra la IU en WPF, sino contra DATA. Lo que realmente te importa es DATA (The ViewModel), no la UI en sí misma.

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

Use un controlador de eventos adjunto

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

esto se llamará para cada cuadro de texto dentro del elemento que llama. Entonces, si coloca eso en su ventana, cada cuadro de texto KeyDownEvent se remenda al método del controlador de eventos MyFieldClick. El remitente es en este caso el cuadro de texto que originalmente envió el evento.

Pero estoy de acuerdo con HighCore, debería utilizar WPF más. En su caso veo ItemControls y una Grilla o mejor un UniformGridPanel.

Btw TextChanged podría ser el evento más apropiado para su caso.