Click here to Skip to main content
15,895,746 members
Articles / Desktop Programming / XAML

Extending GridView with Drag and Drop for Grouping and Variable Sized Items

,
Rate me:
Please Sign up or sign in to vote.
4.98/5 (23 votes)
9 Oct 2015CPOL11 min read 135.4K   8K   69  
This article describes the implementation of an extended GridView control that enables drag and drop with grouping and variable sized items.
<common:LayoutAwarePage
    x:Name="pageRoot"
    x:Class="GridViewSamples.Samples.Grouped"
    DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:GridViewSamples.Samples"
    xmlns:common="using:GridViewSamples.Common"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Page.Resources>
        <DataTemplate x:Key="ItemTemplate">
            <Grid>
                <Border BorderThickness="1" Height="200" Width="200">
                    <Border.Background>
                        <SolidColorBrush Color="{Binding GroupColor}"/>
                    </Border.Background>
                </Border>
                <Grid Margin="12" Background="#88000000">
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <TextBlock Text="{Binding Id}" Margin="5,5,5,0"/>
                    <TextBlock Grid.Row="1" Margin="5,0,5,5">item</TextBlock>
                </Grid>
            </Grid>
        </DataTemplate>
    </Page.Resources>

    <!--
        This grid acts as a root panel for the page that defines two rows:
        * Row 0 contains the back button and page title
        * Row 1 contains the rest of the page layout
    -->
    <Grid Style="{StaticResource LayoutRootStyle}">
        <Grid.RowDefinitions>
            <RowDefinition Height="160"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- Back button and page title -->
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Button x:Name="backButton" Click="GoBack" IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" Style="{StaticResource BackButtonStyle}"/>
            <StackPanel Grid.Column="1" Margin="10">
                <TextBlock x:Name="pageTitle" Style="{StaticResource PageHeaderTextStyle}" >Grouped GridView</TextBlock>
                <TextBlock FontSize="20" >(GridView doesn't allow to use virtualizing panel as GroupStyle.Panel, so can't use WrapGrid here)</TextBlock>
                <TextBlock FontSize="20" >drag&amp;drop doesn't work</TextBlock>
            </StackPanel>
        </Grid>

        <Grid Grid.Row="1">
            <GridView Margin="10" 
                      AllowDrop="True" CanReorderItems="True" CanDragItems="True" IsSwipeEnabled="True"
                      ItemsSource="{Binding}" ItemTemplate="{StaticResource ItemTemplate}" >
                <GridView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </GridView.ItemsPanel>
                <GridView.GroupStyle>
                    <GroupStyle>
                        <GroupStyle.HeaderTemplate>
                            <DataTemplate>
                                <Grid Background="LightGray" Margin="0">
                                    <TextBlock Foreground="Black" Margin="10" Style="{StaticResource GroupHeaderTextStyle}">
                                        <Run Text="{Binding Id}"/><Run Text=" group"/>
                                    </TextBlock>
                                </Grid>
                            </DataTemplate>
                        </GroupStyle.HeaderTemplate>

                        <GroupStyle.ContainerStyle>
                            <Style TargetType="GroupItem">
                                <Setter Property="BorderBrush" Value="DarkGray"/>
                                <Setter Property="BorderThickness" Value="2"/>
                                <Setter Property="Margin" Value="3,0"/>
                            </Style>
                        </GroupStyle.ContainerStyle>

                        <GroupStyle.Panel>
                            <ItemsPanelTemplate>
                                <VariableSizedWrapGrid ItemHeight="100" ItemWidth="100"/>
                            </ItemsPanelTemplate>
                        </GroupStyle.Panel>
                    </GroupStyle>
                </GridView.GroupStyle>
            </GridView>
        </Grid>

        <VisualStateManager.VisualStateGroups>

            <!-- Visual states reflect the application's view state -->
            <VisualStateGroup x:Name="ApplicationViewStates">
                <VisualState x:Name="FullScreenLandscape"/>
                <VisualState x:Name="Filled"/>

                <!-- The entire page respects the narrower 100-pixel margin convention for portrait -->
                <VisualState x:Name="FullScreenPortrait">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PortraitBackButtonStyle}"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>

                <!-- The back button and title have different styles when snapped -->
                <VisualState x:Name="Snapped">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="backButton" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedBackButtonStyle}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="pageTitle" Storyboard.TargetProperty="Style">
                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedPageHeaderTextStyle}"/>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</common:LayoutAwarePage>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Program Manager GrapeCity
Russian Federation Russian Federation
I'm the GrapeCity program manager for ComponentOne Studio.
If you need more info, learn about our products here: http://www.grapecity.com/

Written By
Product Manager GrapeCity
United States United States
I am the ComponentOne product manager at GrapeCity. I love .NET but especially the XAML platforms. You'll find me blogging about these awesome technologies and at various code camps, techfests and tradeshows.

Comments and Discussions