Получение значения TextBlock внутри ComboBox DataTemplate - PullRequest
4 голосов
/ 09 августа 2010

У меня есть следующий 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>

В C # я пытаюсь получить значение TextBlock, которое находится в текущем выбранном элементе в ComboBox.Как я могу это сделать? Этот вопрос почти такой же, но единственный ответ не помогает.

Ответы [ 4 ]

0 голосов
/ 01 декабря 2015

Другие уже предложили использовать событие SelectionChanged. Код ниже не тестировался, но вы можете попробовать.

private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e)
{
    TextBlock tvContent = (sender as ComboBox).SelectedItem as TextBlock;

    string content = tvContent.Text;
}
0 голосов
/ 31 октября 2011

Извините, что немного опоздал на вечеринку :), но также работает следующее (по иронии судьбы было в том же положении, что и вы !!)

TextBlock tb1 = (TextBlock)cbo_team.SelectedItem;
MessageBox.Show(tb1.Text);
0 голосов
/ 30 мая 2012
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 голосов
/ 09 августа 2010

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

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>

Код позади, показывающий, как получить текст напрямую, обходя визуальное дерево:

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