【问题标题】:Problem with traversing WPF element tree遍历WPF元素树的问题
【发布时间】:2010-11-30 22:59:48
【问题描述】:

我有一个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。这里要注意的重要一点是,不能简单地通过调用从列表中获取所选项目,因为我在窗口中有多个列表,并且所有这些列表都实现相同的数据模板,即共享相同的事件处理程序删除按钮。

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

【问题讨论】:

    标签: wpf wpf-controls elementtree


    【解决方案1】:

    如果我正确理解了这个问题,我认为您将能够从 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;
    }
    

    【讨论】:

    • 正确!很好。我不知道 DataContext 属性。值得一提的是,我可以通过调用VisualTreeHelper.GetParent(DependencyObject reference) 方法在元素树中找到自己的方法,但这是一个更好的解决方案!谢谢。
    • 我更喜欢第一个解决方案。感谢发帖!
    • @Boris:当然!是的,第一个版本肯定更好 :) 添加了第二个版本,因为我不确定您是否需要相应的 ListBox
    【解决方案2】:

    您可以尝试使用VisualTreeHelper.GetParent 来遍历可视化树,而不是依赖逻辑父级。

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

    【讨论】:

    • 感谢您的回复。包装 Person 是一个聪明的想法,但是,Meleak 提供的解决方案基本上是我目前所需要的。干杯。
    猜你喜欢
    • 2017-09-22
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    • 2020-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多