遍历WPF元素树的问题

时间:2010-11-30 22:59:49

标签: wpf wpf-controls elementtree

我有一个ListBox数据绑定到我的PersonCollection类的集合。接下来,我为Person类型的对象定义了一个数据模板,其中包含DockPanel,其中包含TextBlock个人姓名和Button以从中删除此人列表。它看起来非常好。

我遇到的问题是,当我单击数据模板中定义的按钮时,我无法在列表框中找到所选项目(并将其删除)。这是按钮的处理程序:

private void RemovePersonButton_Click(object sender, RoutedEventArgs e)
{
    Button clickedButton = (Button)e.Source;
    DockPanel buttonPanel = (DockPanel)clickedButton.Parent;
    Control control = (Control)button.Parent;
}

最后创建的对象controlnull,即我无法在元素树中继续前进,因此无法访问列表及其SelectedItem。这里要注意的重要一点是,不能简单地通过调用从列表中获取所选项目,因为我在窗口中有多个列表,并且所有这些列表实现相同的数据模板,即共享相同的事件处理程序删除按钮。

我很感激能得到的所有帮助。谢谢。

2 个答案:

答案 0 :(得分:3)

如果我正确理解了这个问题,我认为你将能够从Button的DataContext中获取Person

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

另一种方法是在VisualTree中找到ListBox

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

答案 1 :(得分:0)

您可以尝试使用VisualTreeHelper.GetParent来移动可视树,而不是依赖逻辑父。

也就是说,您可以考虑是否可以使用其他上下文信息将Person包装在PersonItem类中,以便PersonItem知道如何从列表中删除Person。我有时会使用这种模式,并编写了一个EncapsulatingCollection类,它根据受监视的ObservableCollection中的更改自动实例化包装器对象。