How to extract value from selected TextBlock element in a ListBox?

馋奶兔 提交于 2019-12-11 02:09:53

问题


I'm using a ListBox to display all values contained in Dictionary<> object:

<ListBox Height="519" x:Name="ContactsListBox" Width="460" Margin="0,0,0,0" SelectionChanged="ContactsListBox_SelectionChanged">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="{Binding Key}" Margin="5" Foreground="{StaticResource PhoneAccentBrush}"/>
                    <TextBlock x:Name ="LastNameData" Text="{Binding Value}" Margin="20, 0" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
</ListBox>

Content is filled by the following code:

Dictionary<long, Contact> contacts = new Dictionary<long, Contact>();
this.ContactsListBox.ItemsSource = contacts;

Now, I would like to 'know' which specific "Contact" in ListBox is currently selected, either by knowing its Key, or just by extracting value from "LastNameData" TextBlock.

I tried doing something like that, but obviosly it doesn't work:

private void ContactsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ListBox lb = this.ContactsListBox.SelectedItem as ListBox;
    this.Test_SomeOtherTextBlock.Text = lb.ToString();
}

I would really appreciate your help!


回答1:


There are several problems:

In Xaml you probably don't want to display the class name, but a reasonable string, for example:

<TextBlock x:Name ="LastNameData" Text="{Binding Value.LastName}" Margin="20, 0" />

In the selection processing the selected item is KeyValuePair<...>. You could easily find it yourself, if you looked at the returned type in debugger. (Should be kind of a reflex for a programmer, hence a questions like above should never appear :))

private void ContactsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { 
    KeyValuePair<long, Contact> kv = (KeyValuePair<long, Contact>)this.ContactsListBox.SelectedItem;
    Contact c = (Contact)kv.Value;
    Debug.WriteLine(c.LastName);
}



回答2:


you can even do the follwing:

<ListBox Height="519" x:Name="ContactsListBox" Width="460" Margin="0,0,0,0" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <TextBlock Text="{Binding Key}" Margin="5"/>
                        <TextBlock x:Name ="LastNameData" Text="{Binding Value}" Margin="20, 0" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Grid DataContext="{Binding ElementName=ContactsListBox, Path=SelectedItem}" Margin="0,470,0,0">
            <TextBlock Text="{Binding Value}"/>
        </Grid>

So you don't need code behind...

BR,

TJ




回答3:


Your code is good, using ListBox.SelectedItem is the right approach.

I think the problem is that you should cast it as ListBoxItem, not ListBox. And also to get to its value using DataContext, so something like along these lines (not tested, I'm not sure about accessing DataContext value in the last line):

private void ContactsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ListBoxItem lbi = this.ContactsListBox.SelectedItem as ListBoxItem;
    var dataContext = lbi.DataContext;
    this.Test_SomeOtherTextBlock.Text = dataContext.Value.ToString();
}



回答4:


Try this it works for me, will help you to...

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



回答5:



private void ContactsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ListBox lb = this.ContactsListBox.SelectedItem as ListBox;
    this.Test_SomeOtherTextBlock.Text = lb.ToString();
}
will go something like this..

private void ContactsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ListBox lb = this.ContactsListBox.SelectedItem as ListBox;
    DataTemplate template=lb.ContentTemplate;
    //Now here you have to extract the content of the data template 
      and then you need to extract the TextBlock from that content.

}

This is just an overview of the functionality.Sorry not able to post complete code.

来源:https://stackoverflow.com/questions/6213669/how-to-extract-value-from-selected-textblock-element-in-a-listbox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!