Check this sample out. The textblock (below the combobox) is showing the value of the name attribute of the currently selected xml element in the combobox. A message box will popup with the same result from the lookup in the visual tree. The lookup fails on initial selection changed. Looks like comboboxitems are created after selected item is set.
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 the text directly by traversing 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;
}