Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XAML/C#: What event fires after reordering a gridview?

I am making my first Windows Store app in Visual Studios 2012. I have a gridview control that I have enabled to be reordered. I have code that I need to run when the list is reordered. I have tried the Drop event. It does not fire. I tried several other drag events, which also did not fire. It seems like this should be so simple... Thanks for your time!

like image 336
Pratt Hinds Avatar asked May 05 '13 20:05

Pratt Hinds


People also ask

What is XAML C#?

XAML is a new descriptive programming language developed by Microsoft to write user interfaces for next-generation managed applications. XAML is the language to build user interfaces for Windows and Mobile applications that use Windows Presentation Foundation (WPF), UWP, and Xamarin Forms.

What replaced XAML?

The XAML Previewer has been deprecated in Visual Studio 2019 version 16.8 and Visual Studio for Mac version 8.8, and replaced by the XAML Hot Reload feature in Visual Studio 2019 version 16.9 and Visual Studio for Mac version 8.9.

Is WPF and C# same?

C# is a programming language. WPF is a technology used to develop rich GUI applications using C# (or any other . NET language).

Is WPF phased out?

“WPF would be dead in 2022 because Microsoft doesn't need to be promoting non-mobile and non-cloud technology. But WPF might be alive in that sense if it's the best solution for fulfilling specific customer needs today. Therefore, having a hefty desktop application needs to run on Windows 7 PCs with IE 8.


1 Answers

You cannot reorder a GridView unless the ItemsSource is bound to an ObservableCollection and CanReorderItems, CanDragItems, and AllowDrop are set to true. It is not necessary to use a CollectionViewSource to enable reordering in your gridview. In fact, a collectionviewsource is often used for grouping a gridview and reordering is not possible when data is grouped.

Anyway, your XAML would look like this:

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

Although any enumerable can be bound to the ItemsSource of a GridView it is only an ObservableCollection that enables reorder. Yes, you can use a custom type that implements reorder, but why mess with that when ObservableCollection does it for you?

Your view model might look like this:

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

In the code above, the reorder event is not real. It is derived from a combination of the "Remove" action and the "Add" action in the CollectionChanged event. Here's why this is awesome. If the reorder was only available from the GridView then the ViewModel would not be able to handle it. Because the underlying list is how you detect reorder, the ViewModel is enabled.

Every case is slightly different. You may not care about the Index so you can simplify the code. You may not allow adding or removing from the collection so you only need to monitor the Add action. Again, it depends on your situation. My sample code above should get 99% of the cases taken care of.

Remember, GridView is not the only control that allows reorder. Any control based on ListViewBase (like the ListView) supports reorder - still using ObservableCollection. But GridView is the most common control to use this feature. For sure.

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

Oh, to answer your question!

There is no event that indicates a reorder. Reorder is a derived action based on a combination of actions in the underlying ObservableCollection CollectionChanged event. Make sense?

By the way, here's sample syntax to bind to a CollectionViewSource, if you choose to:

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

Best of luck.

like image 177
Jerry Nixon Avatar answered Oct 23 '22 09:10

Jerry Nixon