2013-05-05 6 views
9

Tworzę swoją pierwszą aplikację Windows Store w Visual Studio 2012. Mam kontrolę gridview, którą umożliwiłem zmianę kolejności. Mam kod, który muszę uruchomić po zmianie kolejności list. Próbowałem zdarzenia Drop. Nie strzela. Wypróbowałem kilka innych zdarzeń przeciągania, które również nie wystrzeliły. Wygląda na to, że powinno być tak proste ... Dziękuję za poświęcony czas!XAML/C# Jakie zdarzenie zostanie wywołane po zmianie kolejności widoku siatki?

+1

Można użyć 'zdarzenie CollectionChanged' z' 'ObservableCollection , jeśli podałeś' ItemsSource' od '' GridView' z ObservableCollection ' – Xyroid

Odpowiedz

21

Nie można zmienić kolejność GridView ile ItemsSource jest związany z ObservableCollection i CanReorderItems, CanDragItems i AllowDrop są ustawione na true. Jest nie konieczne, aby użyć CollectionViewSource, aby umożliwić zmianę kolejności w swoim gridview. W rzeczywistości, do grupowania collectionviewsource jest często używany gridview, a zmiana kolejności nie jest możliwa, gdy dane są pogrupowane.

Zresztą Twój XAML będzie wyglądać następująco:

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

Chociaż każdej enumerable może być związany z ItemsSource z GridView jest to tylko ObservableCollection które pozwala kolejność. Tak, możesz użyć niestandardowego typu, który implementuje zmianę kolejności, ale po co to robić, gdy ObservableCollection robi to za Ciebie?

Państwa zdanie wzór może wyglądać następująco:

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); 
    } 
} 

W kodzie powyżej, Reorder event nie jest prawdziwe. Pochodzi z kombinacji akcji "Usuń" i akcji "Dodaj" w wydarzeniu CollectionChanged. Oto dlaczego jest to niesamowite. Jeśli zmiana kolejności była dostępna tylko z poziomu GridView, wówczas ViewModel nie byłby w stanie jej obsłużyć. Ponieważ podstawową listą jest sposób wykrywania zmiany kolejności, włączono opcję ViewModel.

Każdy przypadek jest nieco inny. Możesz nie dbać o indeks, aby uprościć kod. Nie możesz pozwolić na dodawanie lub usuwanie z kolekcji, więc musisz tylko monitorować akcję Dodaj. Ponownie, zależy to od twojej sytuacji. Mój przykładowy kod powyżej powinien otrzymać 99% rozpatrywanych spraw.

Pamiętaj, że GridView to nie jedyna kontrola, która umożliwia zmianę kolejności. Jakakolwiek kontrola oparta na ListViewBase (podobnie jak ListView) obsługuje zmianę kolejności - nadal używa się ObservableCollection. Ale GridView jest najczęstszą formantem do korzystania z tej funkcji. Na pewno.

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

Och, aby odpowiedzieć na to pytanie!

Brak zdarzeń wskazujących na zmianę kolejności. Ponowna kolejność jest operacją wyprowadzoną w oparciu o kombinację działań w zdarzeniu ObservableCollectionCollectionChanged. Ma sens?

Przy okazji, oto próbka składnia do wiązania z CollectionViewSource, jeśli zdecydujesz się:

<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> 

Powodzenia.

+0

Dziękuję bardzo za wyjaśnienie! Bardzo pomocne!! –

+0

Szukałem odpowiedzi na to przez cały dzień - to jest idealne, właśnie to, czego potrzebowałem. –

+0

@ JerryNixon-MSFT Wewnątrz zdarzenia "Items_CollectionChanged" zmieniono, w jaki sposób obsługiwać __adding__ do kolekcji? Ponieważ obecnie __removing__ po __adding__ spowodowałoby 'HandleReorder()' – lbrahim

Powiązane problemy