2013-05-05 13 views
9

Sto realizzando la mia prima app per Windows Store in Visual Studios 2012. Dispongo di un controllo della griglia che ho abilitato per essere riordinato. Ho il codice che ho bisogno di eseguire quando l'elenco viene riordinato. Ho provato l'evento Drop. Non spara. Ho provato diversi altri eventi di trascinamento, che non hanno sparato. Sembra che questo dovrebbe essere così semplice ... Grazie per il tuo tempo!XAML/C#: quale evento si attiva dopo aver riordinato una griglia?

+1

È possibile utilizzare 'evento CollectionChanged' di' 'ObservableCollection , se avete fornito' 'ItemsSource' di GridView' con' 'ObservableCollection Xyroid

risposta

21

Non è possibile riordinare un GridView a meno che il ItemsSource è associata a un ObservableCollection e CanReorderItems, CanDragItems, e AllowDrop sono impostati per true. È non necessario per utilizzare un CollectionViewSource per abilitare il riordino nel proprio gridview. Infatti, uno collectionviewsource viene spesso utilizzato per il raggruppamento di gridview e il riordinamento non è possibile quando i dati sono raggruppati.

In ogni caso, il vostro XAML sarebbe simile a questa:

<Grid Background="Black"> 
    <Grid.DataContext> 
     <local:MyModel/> 
    </Grid.DataContext> 
    <GridView CanReorderItems="True" CanDragItems="True" AllowDrop="True" 
       ItemsSource="{Binding Items}"> 
    </GridView> 
</Grid> 

Anche se qualsiasi enumerable può essere vincolato alla ItemsSource di un GridView è solo un ObservableCollection che consente di riordino. Sì, puoi utilizzare un tipo personalizzato che implementa l'ordine di riordino, ma perché farlo funzionare quando lo fa ObservableCollection?

Il vostro modello di vista potrebbe assomigliare a questo:

public class MyModel 
{ 
    public MyModel() 
    { 
     foreach (var item in Enumerable.Range(1, 50)) 
      Items.Add(item); 
     Items.CollectionChanged += Items_CollectionChanged; 
    } 

    ObservableCollection<int> m_Items = new ObservableCollection<int>(); 
    public ObservableCollection<int> Items { get { return m_Items; } } 

    object m_ReorderItem; 
    int m_ReorderIndexFrom; 
    void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     switch (e.Action) 
     { 
      case NotifyCollectionChangedAction.Remove: 
       m_ReorderItem = e.OldItems[0]; 
       m_ReorderIndexFrom = e.OldStartingIndex; 
       break; 
      case NotifyCollectionChangedAction.Add: 
       if (m_ReorderItem == null) 
        return; 
       var _ReorderIndexTo = e.NewStartingIndex; 
       HandleReorder(m_ReorderItem, m_ReorderIndexFrom, _ReorderIndexTo); 
       m_ReorderItem = null; 
       break; 
     } 
    } 

    void HandleReorder(object item, int indexFrom, int indexTo) 
    { 
     Debug.WriteLine("Reorder: {0}, From: {1}, To: {2}", item, indexFrom, indexTo); 
    } 
} 

Nel codice precedente, il riordino event non è reale. Deriva da una combinazione dell'azione "Rimuovi" e dell'azione "Aggiungi" nell'evento CollectionChanged. Ecco perché questo è impressionante. Se il riordino era disponibile solo da GridView, lo ViewModel non sarebbe in grado di gestirlo. Poiché l'elenco sottostante è il modo in cui si rileva l'ordine, lo ViewModel è abilitato.

Ogni caso è leggermente diverso. Potresti non interessarti dell'indice in modo da poter semplificare il codice. Non è possibile consentire l'aggiunta o la rimozione dalla raccolta, quindi è sufficiente monitorare l'azione Aggiungi. Di nuovo, dipende dalla tua situazione. Il mio codice di esempio sopra dovrebbe ottenere il 99% dei casi presi in considerazione.

Ricordare che GridView non è l'unico controllo che consente di riordinare. Qualsiasi controllo basato su ListViewBase (come il ListView) supporta l'ordine di riordino - utilizzando ancora ObservableCollection. Ma GridView è il controllo più comune per utilizzare questa funzione. Di sicuro.

Riferimento: http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.listviewbase.canreorderitems

Oh, per rispondere alla tua domanda!

Nessun evento indica un riordinamento. Riordinare è un'azione derivata basata su una combinazione di azioni nell'evento sottostante CollectionChanged. Ha senso?

A proposito, ecco sintassi di esempio per l'associazione a un CollectionViewSource, se si sceglie di:

<Grid Background="Black"> 
    <Grid.DataContext> 
     <local:MyModel/> 
    </Grid.DataContext> 
    <Grid.Resources> 
     <CollectionViewSource x:Name="CVS" Source="{Binding Items}" /> 
    </Grid.Resources> 
    <GridView CanReorderItems="True" CanDragItems="True" AllowDrop="True" 
       ItemsSource="{Binding Source={StaticResource CVS}}" > 
    </GridView> 
</Grid> 

Buona fortuna.

+0

La ringrazio molto per la spiegazione! Molto utile!! –

+0

State cercando una risposta a tutto questo giorno - questo è perfetto, proprio quello di cui avevo bisogno. –

+0

@ JerryNixon-MSFT All'interno dell'evento 'Items_CollectionChanged' modificato, come gestirò __adding__ nella raccolta? Poiché attualmente __removing__ ha seguito __adding__ risulterebbe in 'HandleReorder()' – lbrahim