2009-09-02 20 views
10

Ho un binding ListView a un ItemsSource. Perché l'evento SelectionChanged si attiva sugli eventi load/databound? Presumo che ciò sia dovuto al fatto che sono selezionati elementi "predefiniti", ovvero l'indice 0.WPF Listview SelectionChanged event

Come posso disabilitare questo, perché quando si seleziona un elemento aggiornato altre fonti con i dati.

Grazie Petrus

+0

Hey Petrus. Potresti per favore condividere il tuo codice? – Anvaka

risposta

1

grazie per le risposte.

Quando si inserisce un punto di interruzione nell'evento SelectionChanged, si interrompe il procedimento prima che lo schermo sia completamente caricato. Vedrai anche che la prima riga è 'selezionata' in seguito sulla lista. Non sto legando a SelectedIndexValue come potete vedere nel codice. Il DataContext per l'elenco è ReadonlyCollection

Nel mio evento SelectionChanged, come è possibile vedere, notifico altri oggetti da caricare con i dati relativi all'elemento selezionato. Voglio solo che questo accada quando uno è selezionato ma non uno di default da impostare. Devo di queste ListViews che rappresentano dati simili ma su nessuno caricato deve avere un elemento selezionato.

Ho notato che l'indice di default selezionato è impostato su -1 nella finestra delle proprietà per Listview. Posso anche impostare questo codice nell'evento List_Loaded, ma a quel punto il primo SelectionChanged è già successo.

<ListView PreviewMouseDown="ActiveCasesView_MouseDown" x:Name="ActiveCasesView" 
        DataContext="{StaticResource ActiveCasesViewSource}" 
        ItemsSource="{Binding}" 
        ItemTemplate="{StaticResource CasesItemTemplate}" 
        SelectionMode="Single" 
        SelectionChanged="ActiveCasesView_SelectionChanged" 
        ScrollViewer.CanContentScroll="True" 
        ScrollViewer.VerticalScrollBarVisibility="Auto" > 
</ListView> 

private void ActiveCasesView_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     if (mouseClicked) 
      if (e.AddedItems.Count > 0) 
       App.Messenger.NotifyColleagues(App.MSG_SELECT_ACTIVE_CASE, ((CaseViewModel)ActiveCasesView.SelectedItem).CaseNumber); 
    } 

ho aggiunto il PreviewMouseDown per impostare un indicatore che ho cliccato sul listview in caso SelectionChanged. Questo aiuta ma non sono convinto che sia la soluzione migliore.

Grazie Petrus

4

ListView non dovrebbero sparare il SelectionChange se si imposta solo la proprietà ItemsSource. Tuttavia, se si associa la proprietà SelectedIndex a una proprietà dell'oggetto dataContext, la selezione si sposterà all'indice specificato dalla proprietà binded.

ciò non genera l'evento Selector_OnSelectionChanged al caricamento della pagina:

<ListView SelectionChanged="Selector_OnSelectionChanged" 
        ItemsSource="{Binding Path=Items}" 
        ></ListView> 

ma questo:

<ListView SelectionChanged="Selector_OnSelectionChanged" 
        SelectedIndex="{Binding Path=SelectedIndexValue}" 
        ItemsSource="{Binding Path=Items}" 
        ></ListView> 

perché il SelectedIndex è impostato al SelecteIndexValue attraverso il legame.

Per evitare questo e mantenere i binding nel markup, impostare SelectedIndexValue dell'oggetto dataContext su -1 prima del binding (Prima che InitializeComponent() venga chiamato nel costruttore del modulo).

Spero che questo aiuti.

0

Si può cercare di impostare la proprietà SelectedIndex a -1 nella vostra vincolante, ma anche questo non è una soluzione elegante.

<ListView PreviewMouseDown="ActiveCasesView_MouseDown" x:Name="ActiveCasesView" 
        DataContext="{StaticResource ActiveCasesViewSource}" 
        ItemsSource="{Binding}" 
        ItemTemplate="{StaticResource CasesItemTemplate}" 
        SelectionMode="Single" 
        SelectionChanged="ActiveCasesView_SelectionChanged" 
        ScrollViewer.CanContentScroll="True" 
        ScrollViewer.VerticalScrollBarVisibility="Auto" 
**SelectedIndex="-1"**> 
</ListView> 

Ho provato a riprodurre il tuo comportamento ma senza successo. Qual è il tipo della raccolta ItemsSource a cui si sta vincolando?

+0

Ho eseguito il binding a ReadonlyCollection di un ViewModel personalizzato. – Petrus

0

finestra caricato evento è possibile utilizzare per bloccare l'azione

bool loaded = false; 

window.Loaded += new RoutedEventHandler(MainWindow_Loaded); 

void MainWindow_Loaded(object sender, RoutedEventArgs e) 
{ 
    windowLoaded = true; 
} 

private void ActiveCasesView_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) 
{ 

if(!loaded) 
return ; 

//do actions here .... 

} 
+0

In tal caso, il primo elemento può essere stappato. –

1

Non so se hai ancora bisogno di aiuto con questo, ma ho risolto questo problema facendo una variabile che tiene traccia del selectedIndex, a mio caso - quando inizialmente rilegato è sempre 0 quindi è un po 'più facile da fare, tuttavia se si informa il viewmodel dell'indice appropriato, ho semplicemente aggiunto uno

ComboBox box = e.OriginalSource as ComboBox; 
if (_previousIndex == cb.SelectedIndex) return; 
//do stuff you need to do with a new SelectedIndex