Проблема с обходом дерева элементов WPF - PullRequest
1 голос
/ 01 декабря 2010

У меня есть 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;
}

Последний созданный объект control - это null, т.е. я не могу продвинуться дальше по дереву элементов, поэтому не могу добраться до списка и его SelectedItem.Здесь важно отметить, что нельзя просто получить выбранный элемент из списка, вызвав его, потому что у меня более одного списка в окне, и все эти списки реализуют один и тот же шаблон данных, то есть используют один и тот же обработчик событий длякнопка удаления.

Буду признателен за любую помощь, которую смогу получить.Благодарю.

Ответы [ 2 ]

3 голосов
/ 01 декабря 2010

Если я правильно понимаю вопрос, я думаю, вы сможете получить человека из 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);
    }
}

Другой способ - найти ListBox в 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;
}
0 голосов
/ 01 декабря 2010

Вы можете попробовать использовать VisualTreeHelper.GetParent для обхода визуального дерева, а не полагаться на логического родителя.

Тем не менее, вы можете подумать, можете ли вы обернуть вашего Person в класс PersonItem с дополнительной контекстной информацией, чтобы PersonItem знал, как удалить Person из списка. Иногда я использую этот шаблон, и я написал класс EncapsulationCollection, который автоматически создает экземпляры объектов-оболочек на основе изменений в отслеживаемой коллекции ObservableCollection.

...