2009-04-19 12 views
8

Possiedo un ListBox, associato a ObservableCollection.WBox ListBox oggetti con DataTemplates - Come faccio a fare riferimento all'oggetto CLR associato a ListBoxItem dall'interno di DataTemplate?

Ogni ListBoxItem viene visualizzato con DataTemplate. Ho un pulsante nel mio DataTemplate, che quando si fa clic, ha bisogno di un riferimento al membro del ObservableCollection per il DataTemplate. Non riesco a utilizzare la proprietà ListBox.SelectedItem perché l'elemento non viene selezionato quando si fa clic sul pulsante.

Quindi: ho bisogno di capire come impostare correttamente ListBox.SelectedItem quando si passa il mouse o quando si fa clic sul pulsante. O ho bisogno di capire un altro modo per ottenere un riferimento all'oggetto CLR legato allo ListBoxItem a cui appartiene il pulsante. La seconda opzione sembra più pulita, ma in entrambi i casi è probabilmente OK.

segmento di codice semplificato di seguito:

XAML:

<DataTemplate x:Key="postBody"> 
    <Grid> 
     <TextBlock Text="{Binding Path=author}"/> 
     <Button Click="DeleteButton_Click">Delete</Button> 
    </Grid> 
</DataTemplate> 

<ListBox ItemTemplate="{StaticResource postBody}"/> 

C#:

private void DeleteButton_Click(object sender, RoutedEventArgs e) 
{ 
    Console.WriteLine("Where mah ListBoxItem?"); 
} 

risposta

11

persone In generale saranno interessati a un oggetto CLR direttamente legato al ListBoxItem, non il vero e proprio ListBoxItem. Se si ha un elenco dei posti per esempio si potrebbe utilizzare il modello esistente di:

<DataTemplate x:Key="postBody" TargetType="{x:Type Post}"> 
    <Grid> 
    <TextBlock Text="{Binding Path=author}"/> 
    <Button Click="DeleteButton_Click">Delete</Button> 
    </Grid> 
</DataTemplate> 
<ListBox ItemTemplate="{StaticResource postBody}" 
    ItemSource="{Binding Posts}"/> 

e nel code-behind, i tuoi Button 's DataContext è pari ai tuoi DataTemplate' s DataContext. In questo caso uno Post.

private void DeleteButton_Click(object sender, RoutedEventArgs e){ 
    var post = ((Button)sender).DataContext as Post; 
    if (post == null) 
    throw new InvalidOperationException("Invalid DataContext"); 

    Console.WriteLine(post.author); 
} 
+0

Questo è perfetto, e sei riuscito a correggere anche la formulazione della mia domanda. Lo modifico come hai ragione, mi interessa l'oggetto CLR associato, non lo stesso ListBoxItem. –

3

Hai diverse possibilità, a seconda di cosa devi fare.

In primo luogo, la domanda principale è: "perché hai bisogno di questo"? La maggior parte delle volte, non esiste un vero uso per un riferimento all'oggetto del contenitore (non dicendo che questo è il tuo caso, ma dovresti elaborarlo). Se stai legando le tue liste alla lista, raramente c'è un caso.

In secondo luogo, è possibile ottenere l'elemento dalla casella di riepilogo, utilizzando myListBox.ItemContainerGenerator.ContainerFromItem(), a condizione che la casella di riepilogo sia denominata MyListBox. Dal parametro del mittente, si può tornare indietro l'elemento effettivo che è stato su modelli attraverso, ad esempio (dove XXX è il tipo di dati che si databound):

Container = sender as FrameworkElement; 
if(sender != null) 
{ 
    MyItem = Container.DataContext as XXX; 
    MyElement = MyListBox.ItemContainerGenerator.ContainerFromItem(MyItem); // <-- this is your ListboxItem. 
} 

Si può trovare un esempio di un this blog. Lei usa il metodo index, ma il metodo Item è simile.

+0

Buona risposta alla domanda come originariamente formulata. bendewey ha assunto correttamente che non intendevo quello che ho detto di aver fatto, ma anche questo è apprezzato. Votato. –

Problemi correlati