2009-07-01 5 views
17

Oh, amico. Mi sento il dolore WPF questa settimana. Quindi, per il mio prossimo trucco, ora non riesco a capire come selezionare un elemento a livello di codice in un ListView.WPF ListView al livello di programmazione Seleziona l'articolo

Sto tentando di utilizzare ItemContainerGenerator di listview, ma non sembra funzionare. Ad esempio, obj è null dopo la seguente operazione:

//VariableList is derived from BindingList 
m_VariableList = getVariableList(); 
lstVariable_Selected.ItemsSource = m_VariableList; 
var obj = 
    lstVariable_Selected.ItemContainerGenerator.ContainerFromItem(m_VariableList[0]); 

Ho provato (sulla base dei suggerimenti visto qui e in altri luoghi) ad usare evento StatusChanged del ItemContainerGenerator, ma senza alcun risultato. L'evento non si accende mai. Per esempio:

m_VariableList = getVariableList(); 
lstVariable_Selected.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged); 
lstVariable_Selected.ItemsSource = m_VariableList; 

... 

void ItemContainerGenerator_StatusChanged(object sender, EventArgs e) 
{ 
    //This code never gets called 
    var obj = lstVariable_Selected.ItemContainerGenerator.ContainerFromItem(m_VariableList[0]); 
} 

Il punto cruciale di tutta questa faccenda è che voglio semplicemente di preselezionare alcuni degli articoli nel mio ListView.

Nell'interesse di non tralasciare nulla, ListView utilizza alcune funzionalità di template e di trascinamento/rilascio, quindi includo qui l'XAML. In sostanza, questo modello rende ogni elemento una casella di testo con del testo e quando viene selezionato un elemento, la casella di controllo è selezionata. E ogni elemento ottiene anche un po 'glifo sotto per inserire nuovi elementi (e questo tutto funziona bene):

<DataTemplate x:Key="ItemDataTemplate_Variable"> 
<StackPanel> 
    <CheckBox x:Name="checkbox" 
     Content="{Binding Path=ListBoxDisplayName}" 
     IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}, Path=IsSelected}" /> 
    <Image ToolTip="Insert Custom Variable" Source="..\..\Resources\Arrow_Right.gif" 
     HorizontalAlignment="Left" 
     MouseLeftButtonDown="OnInsertCustomVariable" 
     Cursor="Hand" Margin="1, 0, 0, 2" Uid="{Binding Path=CmiOrder}" /> 
</StackPanel> 
</DataTemplate> 

... 

<ListView Name="lstVariable_All" MinWidth="300" Margin="5" 
    SelectionMode="Multiple" 
    ItemTemplate="{StaticResource ItemDataTemplate_Variable}" 
    SelectionChanged="lstVariable_All_SelectionChanged" 
    wpfui:DragDropHelper.IsDropTarget="True" 
    wpfui:DragDropHelper.IsDragSource="True" 
    wpfui:DragDropHelper.DragDropTemplate="{StaticResource ItemDataTemplate_Variable}" 
     wpfui:DragDropHelper.ItemDropped="OnItemDropped"/> 

Allora, cosa mi manca? Come faccio a selezionare a livello di programmazione uno o più elementi in ListView?

Mille grazie per il vostro tempo.

risposta

30

Associare la proprietà IsSelected di ListViewItem a una proprietà sul modello. Quindi, è necessario lavorare solo con il modello piuttosto che preoccuparsi delle complessità dell'interfaccia utente, che include potenziali rischi per la virtualizzazione dei contenitori.

Ad esempio:

<ListView> 
    <ListView.ItemContainerStyle> 
     <Style TargetType="ListViewItem"> 
      <Setter Property="IsSelected" Value="{Binding IsGroovy}"/> 
     </Style> 
    </ListView.ItemContainerStyle> 
</ListView> 

Ora, solo lavoro con la proprietà del vostro modello IsGroovy per selezionare/deselezionare elementi nella ListView.

+2

Ma ovviamente. Associazione dati. Non tutti i problemi in WPF si riducono ad un certo punto per l'associazione dei dati? Grazie, Kent. –

+0

Questa è una soluzione davvero carina, complimenti! –

+4

Basta citare: questa soluzione non funziona sull'app di Windows Store. Invece dovresti impostare il binding nel codice, in questo modo: http: //social.msdn.microsoft.com/Forums/windowsapps/en-US/9a0adf35-fdad-4419-9a34-a9dac052a2e3/listviewitemisselected-data-binding-in in stile-setter-is-not-working? forum = winappswithcsharp – SimonFisher

4

Qui sarebbe la mia ipotesi migliore, che sarebbe un metodo molto più semplice per la selezione. Dal momento che non sono sicuro di quello che si sta selezionando su, ecco un esempio generico:

var indices = new List<int>(); 

for(int i = 0; i < lstVariable_All.Items.Count; i++) 
{ 
    // If this item meets our selection criteria 
    if(lstVariable_All.Items[i].Text.Contains("foo")) 
    indices.Add(i); 
} 

// Reset the selection and add the new items. 
lstVariable_All.SelectedIndices.Clear(); 

foreach(int index in indices) 
{ 
    lstVariable_All.SelectedIndices.Add(index); 
} 

Quello che sono abituato a vedere è un SelectedItem impostabile, ma vedo non è possibile impostare o aggiungere a questo, ma spero che questo metodo funzioni come sostituto.

3

Dove 'this' è l'istanza di ListView. Questo non solo cambierà la selezione, ma metterà anche a fuoco l'elemento appena selezionato.

private void MoveSelection(int level) 
    { 
    var newIndex = this.SelectedIndex + level; 
    if (newIndex >= 0 && newIndex < this.Items.Count) 
    { 
     this.SelectedItem = this.Items[newIndex]; 
     this.UpdateLayout(); 
     ((ListViewItem)this.ItemContainerGenerator.ContainerFromIndex(newIndex)).Focus(); 
    } 
    }