У меня есть данные 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 ответа
Если я правильно понимаю вопрос, я думаю, вы сможете получить человека из 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;
}
Вы можете попробовать использовать VisualTreeHelper.GetParent обходить визуальное дерево, а не полагаться на логического родителя.
Тем не менее, вы можете подумать, можете ли вы обернуть свой Person в класс PersonItem с дополнительной контекстной информацией, чтобы PersonItem знал, как удалить Person из списка. Иногда я использую этот шаблон, и я написал класс EncapsulatingCollection, который автоматически создает экземпляры объектов-оболочек на основе изменений в отслеживаемой ObservableCollection.
Похожие вопросы
Новые вопросы
wpf
Windows Presentation Foundation, или WPF, является подсистемой для визуализации пользовательских интерфейсов в приложениях на основе Windows.
DataContext
. Как бы то ни было, я смог разобраться в дереве элементов, вызвав методVisualTreeHelper.GetParent(DependencyObject reference)
, но это гораздо лучшее решение! Спасибо.