Как получить доступ к определенному элементу в списке с помощью DataTemplate?

У меня есть ListBox, включая ItemTemplate с 2 StackPanels. Во втором стеке, которое я хочу получить, есть TextBox. (Измените его видимость на true и примите ввод пользователя) Триггер должен быть SelectionChangedEvent. Таким образом, если пользователь нажимает на ListBoxItem, TextBlock становится невидимым, и TextBox становится видимым.

КОД XAML:

                          

Я думаю, есть несколько способов решить эту проблему, но я ничего не пробовал.

Мой текущий подход выглядит так

  private void ContactListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { ListBoxItem listBoxItem = ContactListBox.SelectedItem as ListBoxItem; DataTemplate listBoxTemplate = listBoxItem.ContentTemplate; // How to access the DataTemplate content? StackPanel outerStackPanel = listBoxTemplate.XXX as StackPanel; StackPanel innerStackPanel = outerStackPanel.Children[1] as StackPanel; TextBox nameBox = innerStackPanel.Children[0] as TextBox; TextBlock nameBlock = innerStackPanel.Children[1] as TextBlock; nameBox.Visibility = System.Windows.Visibility.Visible; nameBlock.Visibility = System.Windows.Visibility.Collapsed; } 

Спасибо вам за помощь! Наконец то я понял. Решена проблема с VisualTreeHelper. Какая замечательная функция ^^

 private void ContactListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (ContactListBox.SelectedIndex == -1) return; currentSelectedListBoxItem = this.ContactListBox.ItemContainerGenerator.ContainerFromIndex(ContactListBox.SelectedIndex) as ListBoxItem; if (currentSelectedListBoxItem == null) return; // Iterate whole listbox tree and search for this items TextBox nameBox = helperClass.FindDescendant(currentSelectedListBoxItem); TextBlock nameBlock = helperClass.FindDescendant(currentSelectedListBoxItem); 

helperFunction

 public T FindDescendant(DependencyObject obj) where T : DependencyObject { // Check if this object is the specified type if (obj is T) return obj as T; // Check for children int childrenCount = VisualTreeHelper.GetChildrenCount(obj); if (childrenCount < 1) return null; // First check all the children for (int i = 0; i < childrenCount; i++) { DependencyObject child = VisualTreeHelper.GetChild(obj, i); if (child is T) return child as T; } // Then check the childrens children for (int i = 0; i < childrenCount; i++) { DependencyObject child = FindDescendant(VisualTreeHelper.GetChild(obj, i)); if (child != null && child is T) return child as T; } return null; } 

С помощью этой отредактированной функции вы также можете искать элемент управления по имени (его преобразование из VB.NET):

 public T FindDescendantByName(DependencyObject obj, string objname) where T : DependencyObject { string controlneve = ""; Type tyype = obj.GetType(); if (tyype.GetProperty("Name") != null) { PropertyInfo prop = tyype.GetProperty("Name"); controlneve = prop.GetValue((object)obj, null); } else { return null; } if (obj is T && objname.ToString().ToLower() == controlneve.ToString().ToLower()) { return obj as T; } // Check for children int childrenCount = VisualTreeHelper.GetChildrenCount(obj); if (childrenCount < 1) return null; // First check all the children for (int i = 0; i <= childrenCount - 1; i++) { DependencyObject child = VisualTreeHelper.GetChild(obj, i); if (child is T && objname.ToString().ToLower() == controlneve.ToString().ToLower()) { return child as T; } } // Then check the childrens children for (int i = 0; i <= childrenCount - 1; i++) { string checkobjname = objname; DependencyObject child = FindDescendantByName(VisualTreeHelper.GetChild(obj, i), objname); if (child != null && child is T && objname.ToString().ToLower() == checkobjname.ToString().ToLower()) { return child as T; } } return null; } 

Я не могу дать вам полный ответ …

Но я думаю, что вы можете использовать VisualTreeHelper для итерации через дочерние элементы любого элемента управления http://blogs.msdn.com/b/kmahone/archive/2009/03/29/visualtreehelper.aspx

Однако для эффекта, который вы ищете, я думаю, что использование метода SelectedItem Style может быть лучшим решением – например, см. Эту статью – http://joshsmithonwpf.wordpress.com/2007/07/30/customizing-the-selected- пункт-в-ListBox /

Поскольку DataTemplate – это общий шаблон, который может использоваться много раз в коде, нет доступа к нему по имени (x: Name = “numberTextBox”).

Я решил схожую проблему с этим, создав коллекцию Controls – при заполнении Listbox я добавляю элемент управления Textbox в коллекцию.

 string text = myCollectionOfTextBoxes[listbox.SelectedIndex].Text; 

До тех пор, пока я не найду лучшее свойство soultion – Tag. В свой ListboxItem вы привязываете свойство тега к имени

 Tag="{Binding Name}" 

и доступ к нему

 ListBoxItem listBoxItem = ContactListBox.SelectedItem as ListBoxItem; string name = listBoxItem.Tag.ToString(); 

Используйте ItemContainerGenerator .

 private void ContactListBox_SelectionChanged (object sender, SelectionChangedEventArgs e) { if (e.AddedItems.Count == 1) { var container = (FrameworkElement)ContactListBox.ItemContainerGenerator. ContainerFromItem(e.AddedItems[0]); StackPanel sp = container.FindVisualChild(); TextBox tbName = (TextBox) sp.FindName("tbName"); TextBlock lblName = (TextBlock)sp.FindName("lblName"); TextBlock lblNumber = (TextBlock)sp.FindName("lblNumber"); } } 
  • Привязать к методу в WPF?
  • Имя не существует в ошибке пространства имен в XAML
  • Приложение WPF, в котором есть только значок в трее
  • Установка свойства с помощью EventTrigger
  • Применение инсульта к текстовому блоку в WPF
  • Вызывающий stream должен быть STA, потому что многие компоненты пользовательского интерфейса требуют этого
  • Взаимоисключающие элементы меню?
  • Какие подходы доступны для фиктивных данных времени разработки в WPF?
  • В чем разница между x: Reference и ElementName?
  • Почему обертки свойств .NET обойдены во время выполнения при настройке свойств зависимостей в XAML?
  • WPF TreeView: как стилизовать выбранные элементы с закругленными углами, как в Explorer
  • Давайте будем гением компьютера.