Click here to Skip to main content
15,894,017 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.3K   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:Class="GridViewSampleC1Tiles.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:GridViewSampleC1Tiles"
    xmlns:common="using:GridViewSampleC1Tiles.Common"
    xmlns:c1tile="using:C1.Xaml.Tile"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <common:LayoutAwarePage.Resources>
        <Style TargetType="c1tile:C1TileBase" x:Key="tileBaseStyle">
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="Padding" Value="0"/>
            <Setter Property="HeaderBackground" Value="#88000000"/>
            <Setter Property="HorizontalHeaderAlignment" Value="Stretch"/>
            <Setter Property="HeaderPadding" Value="5"/>
            <Setter Property="Height" Value="150"/>
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <Border Background="#88000000" Height="80" Width="80" >
                            <TextBlock Text="{Binding}" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White"/>
                        </Border>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <!-- apply same base style settings to all tile types -->
        <Style TargetType="c1tile:C1Tile" BasedOn="{StaticResource tileBaseStyle}"/>
        <Style TargetType="c1tile:C1SlideTile" BasedOn="{StaticResource tileBaseStyle}"/>
        <Style TargetType="c1tile:C1FlipTile" BasedOn="{StaticResource tileBaseStyle}"/>

        <!-- 
        <DataTemplate x:Key="ItemTemplate">
            <c1tile:C1SlideTile Content="{Binding Id}" Header="{Binding GroupId}">
                <c1tile:C1Tile.Background>
                    <SolidColorBrush Color="{Binding GroupColor}"/>
                </c1tile:C1Tile.Background>
            </c1tile:C1SlideTile>
        </DataTemplate>
        -->

        <!-- use different tile types -->
        <local:TileGridViewItemTemplateSelector x:Key="TileGridViewItemTemplateSelector">
            <local:TileGridViewItemTemplateSelector.Resources>
                <ResourceDictionary>
                    <DataTemplate x:Key="ItemTemplate0">
                        <c1tile:C1Tile Content="{Binding Id}" Header="{Binding GroupId}" HorizontalContentAlignment="Stretch">
                            <c1tile:C1Tile.Background>
                                <SolidColorBrush Color="{Binding GroupColor}"/>
                            </c1tile:C1Tile.Background>
                        </c1tile:C1Tile>
                     </DataTemplate>
                    <DataTemplate x:Key="ItemTemplate1">
                        <c1tile:C1SlideTile Content="{Binding Id}" Header="{Binding GroupId}">
                            <c1tile:C1Tile.Background>
                                <SolidColorBrush Color="{Binding GroupColor}"/>
                            </c1tile:C1Tile.Background>
                        </c1tile:C1SlideTile>
                    </DataTemplate>
                    <DataTemplate x:Key="ItemTemplate2">
                        <c1tile:C1FlipTile Content="{Binding Id}" Header="{Binding GroupId}">
                            <c1tile:C1Tile.Background>
                                <SolidColorBrush Color="{Binding GroupColor}"/>
                            </c1tile:C1Tile.Background>
                        </c1tile:C1FlipTile>
                    </DataTemplate>
                    <DataTemplate x:Key="ItemTemplate3">
                        <c1tile:C1FlipTile Content="{Binding Id}" Header="{Binding GroupId}">
                            <c1tile:C1Tile.Background>
                                <SolidColorBrush Color="{Binding GroupColor}"/>
                            </c1tile:C1Tile.Background>
                            <c1tile:C1Tile.BackContentTemplate>
                                <DataTemplate>
                                    <Grid Background="Orange" >
                                        <Image Source="ms-appx:///Assets/Logo.png" Stretch="Uniform" />
                                        <TextBlock Text="{Binding}" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="20" FontWeight="Bold"/>
                                    </Grid>
                                </DataTemplate>
                            </c1tile:C1Tile.BackContentTemplate>
                        </c1tile:C1FlipTile>
                    </DataTemplate>
                </ResourceDictionary>
            </local:TileGridViewItemTemplateSelector.Resources>
        </local:TileGridViewItemTemplateSelector>
    </common:LayoutAwarePage.Resources>

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="160"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- Page title -->
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <StackPanel Grid.Column="1" Margin="10">
                <TextBlock x:Name="pageTitle" Style="{StaticResource PageHeaderTextStyle}" FontSize="28">
                	<Run Text="Customized GridView with live tiles"/>
                </TextBlock>
                <TextBlock FontSize="20" >
                	<Run Text="This sample uses a VariableSizedWrapGrid as GroupStyle.Panel, drag&amp;drop implemented in the GridViewEx class."/>
                </TextBlock>
                <TextBlock FontSize="20" >
                	<Run Text="It also uses C1Tile and C1TileService to mimic the Windows 8 Start screen behavior with animated tiles."/>
                </TextBlock>
            </StackPanel>
        </Grid>

        <Grid Grid.Row="1">
            <local:TileGridView Margin="10" AllowNewGroup="True" BeforeDrop="MyGridView_BeforeDrop" Drop="MyGridView_Drop"
                      AllowDrop="True" CanReorderItems="True" CanDragItems="True" IsSwipeEnabled="True"
                      ItemsSource="{Binding}" ItemTemplateSelector="{StaticResource TileGridViewItemTemplateSelector}" >
                <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"/>
                                <!-- uncommment the below ControlTemplate to include new group placeholders between groups.
                                     The GridViewEx class honors any element with NewGroupPlaceHolder name. -->
                                <!-- 
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="GroupItem">
                                            <StackPanel Orientation="Horizontal" >
                                                <Border Background="{TemplateBinding Background}"
                                                        BorderBrush="{TemplateBinding BorderBrush}"
                                                        BorderThickness="{TemplateBinding BorderThickness}">
                                                    <Grid>
                                                        <Grid.RowDefinitions>
                                                            <RowDefinition Height="Auto" />
                                                            <RowDefinition Height="*" />
                                                        </Grid.RowDefinitions>
                                                        <ContentControl x:Name="HeaderContent"
                                                            Content="{TemplateBinding Content}"
                                                            ContentTransitions="{TemplateBinding ContentTransitions}"
                                                            ContentTemplate="{TemplateBinding ContentTemplate}"
                                                            ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
                                                            Margin="{TemplateBinding Padding}"
                                                            TabIndex="0"
                                                            IsTabStop="False" />
                                                        <ItemsControl x:Name="ItemsControl" Grid.Row="1"
                                                              ItemsSource="{Binding GroupItems}"
                                                              IsTabStop="False"
                                                              TabNavigation="Once"
                                                              TabIndex="1" >
                                                            <ItemsControl.ItemContainerTransitions>
                                                                <TransitionCollection>
                                                                    <AddDeleteThemeTransition />
                                                                    <ContentThemeTransition />
                                                                    <ReorderThemeTransition />
                                                                    <EntranceThemeTransition IsStaggeringEnabled="False" />
                                                                </TransitionCollection>
                                                            </ItemsControl.ItemContainerTransitions>
                                                        </ItemsControl>
                                                    </Grid>
                                                </Border>
                                                <Border Width="40" x:Name="NewGroupPlaceHolder" 
                                                        DataContext="{Binding Group}"
                                                        Background="Transparent" Padding="{TemplateBinding Padding}" />
                                            </StackPanel>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter> 
                                -->
                            </Style>
                        </GroupStyle.ContainerStyle>

                        <GroupStyle.Panel>
                            <ItemsPanelTemplate>
                                <VariableSizedWrapGrid ItemHeight="160" ItemWidth="160" />
                            </ItemsPanelTemplate>
                        </GroupStyle.Panel>
                    </GroupStyle>
                </GridView.GroupStyle>
                <GridView.ItemContainerStyle>
                    <Style TargetType="GridViewItem">
                        <Setter Property="c1tile:C1TileService.PointerDownAnimation" Value="True"/>
                        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                        <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                    </Style>
                </GridView.ItemContainerStyle>
            </local:TileGridView>
        </Grid>

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

                <!-- The have different style when snapped -->
                <VisualState x:Name="Snapped">
                    <Storyboard>
                        <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