在ComboBox DataTemplate中获取TextBlock的价值

时间:2010-08-09 14:55:49

标签: c# wpf combobox datatemplate textblock

我有以下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的值。我怎么做? This question几乎相同,但唯一的答案无济于事。

4 个答案:

答案 0 :(得分:0)

检查此样本。文本块(在组合框下面)显示组合框中当前选定的xml元素的name属性的值。将弹出一个消息框,其结果与可视树中的查找结果相同。初始选择更改时查找失败。看起来在设置所选项目后会创建组合框。

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

答案 1 :(得分:0)

对不起有点迟到了派对:)但是下面也有效(具有讽刺意味的是和你一样的修复!!)

TextBlock tb1 = (TextBlock)cbo_team.SelectedItem;
MessageBox.Show(tb1.Text);

答案 2 :(得分:0)

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

答案 3 :(得分:0)

其他人已经建议使用SelectionChanged事件。没有测试下面的代码,但你可以尝试一下。

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

    string content = tvContent.Text;
}