Getting a TextBlock value inside a ComboBox DataTemplate

I have the following XAML:

<ComboBox Height="23" HorizontalAlignment="Left" Grid.Row="6" Grid.Column="2" Name="cbo_team" VerticalAlignment="Top" Width="148" DataContext="{Binding ElementName=cbo_component, Path=SelectedItem}" SelectedIndex="0"> <ComboBox.ItemsSource> <Binding XPath="Teams/Team/@id" Converter="{StaticResource xmlConverter}"> <Binding.ConverterParameter> <local:XmlConverterParameter XPathTemplate="/Products/Teams/Team[{0}]" XPathCondition="@id='{0}'" /> </Binding.ConverterParameter> </Binding> </ComboBox.ItemsSource> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding XPath=@name }" /> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> 

In C #, I'm trying to get a TextBlock value that is in the currently selected item in a ComboBox . How can I do it? This question is almost the same, but the only answer does not help.

+4
source share
4 answers

Check out this sample. The text block (below the combo box) shows the value of the name attribute of the currently selected xml element in the combo box. A message box appears with the same search result in the visual tree. Search error on initial selection changed. It looks like comboboxitems are created after installing the selected item.

XAML:

 <Window x:Class="CBTest.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="300" Width="300"> <Window.Resources> <XmlDataProvider x:Key="UsersData" XPath="Users"> <x:XData> <Users xmlns=""> <User name="Sally" /> <User name="Lucy" /> <User name="Linus" /> <User name="Charlie" /> </Users> </x:XData> </XmlDataProvider> </Window.Resources> <StackPanel> <ComboBox Name="_comboBox" ItemsSource="{Binding Source={StaticResource UsersData},XPath=*}" SelectedIndex="0" SelectionChanged="OnComboBoxSelectionChanged"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding XPath=@name }" Name="nameTextBlock" /> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> <!-- Below shows how to get the value of selected item directly from the data. --> <TextBlock DataContext="{Binding Path=SelectedItem, ElementName=_comboBox}" Text="{Binding XPath=@name }" /> </StackPanel> </Window> 

Code behind showing how to get text directly by going through the visual tree:

 private void OnComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e) { ComboBox comboBox = sender as ComboBox; ComboBoxItem comboBoxItem = comboBox.ItemContainerGenerator.ContainerFromItem(comboBox.SelectedItem) as ComboBoxItem; if (comboBoxItem == null) { return; } TextBlock textBlock = FindVisualChildByName<TextBlock>(comboBoxItem, "nameTextBlock"); MessageBox.Show(textBlock.Text); } private static T FindVisualChildByName<T>(DependencyObject parent, string name) where T : DependencyObject { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { var child = VisualTreeHelper.GetChild(parent, i); string controlName = child.GetValue(NameProperty) as string; if (controlName == name) { return child as T; } T result = FindVisualChildByName<T>(child, name); if (result != null) return result; } return null; } 
0
source

Sorry a little late to the party :), but the following also works (ironically, it was in the same fix as you!)

 TextBlock tb1 = (TextBlock)cbo_team.SelectedItem; MessageBox.Show(tb1.Text); 
0
source
 private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { ListBox ContactListBox = sender as ListBox; ListBoxItem listBoxItem = ContactListBox .ItemContainerGenerator.ContainerFromItem(ContactListBox.SelectedItem) as ListBoxItem; if (listBoxItem == null) { return; } TextBlock txtBlock = FindVisualChildByName<TextBlock>(listBoxItem, "ListTextBlock"); MessageBox.Show(txtBlock.Text); } private static T FindVisualChildByName<T>(DependencyObject parent, string name) where T : DependencyObject { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { var child = VisualTreeHelper.GetChild(parent, i); string controlName = child.GetValue(NameProperty) as string; if (controlName == name) { return child as T; } T result = FindVisualChildByName<T>(child, name); if (result != null) return result; } return null; } 
0
source

Others have already suggested using the SelectionChanged event. Not tested the code below, but you can try.

 private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e) { TextBlock tvContent = (sender as ComboBox).SelectedItem as TextBlock; string content = tvContent.Text; } 
0
source

All Articles