How to extract value from selected TextBlock element in a ListBox?
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">
<TextBl开发者_如何学Cock 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!
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
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);
}
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();
}
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;
}
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.
精彩评论