Problem with traversing WPF element tree
I have a ListBox
data bound to the collection of my PersonCollection
class. Next, I have defined a data template for objects of type Person
, consisted of a DockPanel
which contains a TextBlock
for a person's name and a Button
to remove the person from the list. It looks very nice all together.
The problem I am facing is that I am unable to reach the selected item (and delete it) in the list box when I click the button defined in the data template. Here's the handler of the button:
private void RemovePersonButton_Click(object sender, RoutedEventArgs e)
{
Button clickedButton = (Button)e.Source;
DockPanel buttonPanel = (DockPanel)clickedButton.Parent;
Control control = (Control)button.Parent;
}
The last created object control
is null
, i.e. I cannot progress further up the element tree, so I cannot reach the list and its SelectedItem
. Important thing to note here is that cannot simply go with getting the selected item from the lis开发者_Python百科t by calling it, because I have more than one list in the window and all those lists implement the same data template, i.e. share the same event handler for the delete button.
I would appreciate all the help I could get. Thanks.
If I understand the question correctly I think you'll be able to get the Person from the Button's DataContext
private void RemovePersonButton_Click(object sender, RoutedEventArgs e)
{
Button clickedButton = (Button)e.Source;
Person selectedItem = clickedButton.DataContext as Person;
if (selectedItem != null)
{
PersonCollection.Remove(selectedItem);
}
}
Another way is to find the ListBox in the VisualTree
private void RemovePersonButton_Click(object sender, RoutedEventArgs e)
{
Button clickedButton = (Button)e.Source;
ListBox listBoxParent = GetVisualParent<ListBox>(clickedButton );
Person selectedItem = listBoxParent.SelectedItem as Person;
//...
}
public T GetVisualParent<T>(object childObject) where T : Visual
{
DependencyObject child = childObject as DependencyObject;
while ((child != null) && !(child is T))
{
child = VisualTreeHelper.GetParent(child);
}
return child as T;
}
You might try using VisualTreeHelper.GetParent to walk the visual tree, rather than relying on the Logical Parent.
That said, you might consider whether you can wrap your Person in a PersonItem class, with additional context information so that the PersonItem knows how to remove the Person from the list. I'll sometimes use this pattern and I wrote an EncapsulatingCollection class that automatically instantiates wrapper objects based on the changes in a monitored ObservableCollection.
精彩评论