Problema con l'attraversamento elemento di albero di WPF
-
29-09-2019 - |
Domanda
Ho un dato ListBox
legati alla raccolta della mia classe PersonCollection
. Successivamente, ho definito un modello di dati per gli oggetti di tipo Person
, consisteva in una DockPanel
che contiene un TextBlock
per il nome di una persona e un Button
per rimuovere la persona dalla lista. Sembra molto bello tutti insieme.
Il problema che sto affrontando è che io sono in grado di raggiungere l'elemento selezionato (ed eliminarlo) nella casella di riepilogo quando si fa clic sul pulsante definito nel modello di dati. Ecco il gestore del pulsante:
private void RemovePersonButton_Click(object sender, RoutedEventArgs e)
{
Button clickedButton = (Button)e.Source;
DockPanel buttonPanel = (DockPanel)clickedButton.Parent;
Control control = (Control)button.Parent;
}
L'ultima control
oggetto creato è null
, vale a dire non riesco a progredire più in alto l'albero elemento, quindi non posso raggiungere la lista e la sua SelectedItem
. Cosa importante da notare qui è che non si può semplicemente andare con ottenere l'elemento selezionato dalla lista chiamandola, perché ho più di una lista nella finestra e tutte quelle liste implementare lo stesso modello di dati, vale a dire condividere lo stesso gestore di eventi per il pulsante Elimina.
I apprezzerebbe tutto l'aiuto ho potuto ottenere. Grazie.
Soluzione
Se ho capito bene la domanda penso che sarete in grado di ottenere la persona dal DataContext del pulsante
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);
}
}
Un altro modo è quello di trovare il ListBox nella 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;
}
Altri suggerimenti
Si potrebbe provare a utilizzare VisualTreeHelper.GetParent di percorrere la struttura visiva, piuttosto che fare affidamento sul padre logico.
Detto questo, si potrebbe prendere in considerazione se si può avvolgere la persona in una classe PersonItem, con informazioni di contesto aggiuntive in modo che il PersonItem sa come rimuovere la persona dalla lista. Io a volte uso questo modello e ho scritto una classe EncapsulatingCollection che automaticamente crea un'istanza involucro oggetti in base alle modifiche in un ObservableCollection monitorati.