Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different item size in a grouped gridView

I created a Grouped GridView with an item template and header template. It works well but then I would like the first article of my list to have a different template (to be bigger). Like the french application "LeMonde" for example. I have no idea of how I could define the template to achieve that.

Here is my current xaml code

<Page.Resources>
 <CollectionViewSource x:Name="cvs1" IsSourceGrouped="True" />
</Page.Resources>

<Grid Background="White">

    <GridView  x:Name="PicturesGridView" SelectionMode="None"
ItemsSource="{Binding Source={StaticResource cvs1}}"IsItemClickEnabled="True"  ItemClick="ItemView_ItemClick">
        <GridView.ItemTemplate>
            <DataTemplate>
                <StackPanel x:Name="RectanglesStackPanel" Margin="8" Orientation="Vertical" Width="242">

                    <Image Source="{Binding imageUrl}" Height="180"  Width="225"   Stretch="UniformToFill" />

                    <Border Background="Gray" Opacity="1" Width="225" Height="115">
                       <TextBlock Text="{Binding title}"
           Foreground="White" TextWrapping="Wrap" Width="215" FontSize="18" />
                    </Border>
                </StackPanel>
            </DataTemplate>
        </GridView.ItemTemplate>
        <GridView.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </GridView.ItemsPanel>
        <GridView.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                         <Button  Click="Button_Click_1" Content="{Binding Key}" Foreground="Black" Background="White" FontSize="30" Margin="0,0,0,-10" ></Button>     
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
                <GroupStyle.Panel>
                    <ItemsPanelTemplate>
                        <VariableSizedWrapGrid Orientation="Vertical" />
                    </ItemsPanelTemplate>
                </GroupStyle.Panel>
            </GroupStyle>
        </GridView.GroupStyle>
    </GridView>


</Grid>

I just bind my list of item in C# like this :

this.cvs1.Source = ListOfArticle;

Thank you in advance :)


Thank you Ivan. It helps me a lot. However the code provided in the example doesn't seem up to date for Windows 8. Do you have any ideas of how we can access a template defined in the ressources of a page. The FindRessources Method doesn't exist anymore. I tried with this code instead but it wasn't successful :

 public class AuctionItemDataTemplateSelector : DataTemplateSelector
 {
    protected override DataTemplate SelectTemplateCore(object item, 
                                                  DependencyObject container)
    {
        FrameworkElement element = container as FrameworkElement;

        if (element != null && item != null && item is Article)
        {
            Article auctionItem = item as Article;

            DataTemplate mySmallTemplate = element.FindName("SmallTemplate") as DataTemplate;

            switch (auctionItem.isFirstItem)
            {
                case true:
                    return
                  element.FindName("BigTemplate") as DataTemplate;

                case false:
                    return
                   element.FindName("SmallTemplate") as DataTemplate;
            }
        }

        return null;
    }
}

'

like image 590
Thomas Salandre Avatar asked Aug 03 '12 15:08

Thomas Salandre


2 Answers

I followed the way of creating a custom DataTemplateSelector with all needed templates as properties.

namespace Helper
{
    public class CustomSampleDataTemplateSelector : DataTemplateSelector
    {
        public DataTemplate FirstDataTemplate { get; set; }

        public DataTemplate SecondDataTemplate { get; set; }

        protected override DataTemplate SelectTemplateCore(object item, 
                  DependencyObject container)
        {
            if (item is FirstItemType)
                return FirstDataTemplate ;
            if (item is SecondItemType)
                return SecondDataTemplate;
            else
                return FirstDataTemplate ;
        }
    }
}

Now you can use it directly in XAML like this:

Declare resource:

<UserControl.Resources>
    <DataTemplate x:Key="myTemplate1">
        <Border Background="White">
            <TextBlock Text="{Binding Name}"
                       FontSize="40"
                       Foreground="Black"
                       HorizontalAlignment="Center"
                       VerticalAlignment="Center" />
        </Border>
    </DataTemplate>
    <DataTemplate x:Key="myTemplate2">
        <Border Background="Orange">
            <Grid>
                <Image Source="{Binding Image}"></Image>
                <TextBlock Text="{Binding ShopName}"
                           FontSize="64"
                           Foreground="LightBlue"
                           HorizontalAlignment="Center"
                           VerticalAlignment="Center" />
            </Grid>
        </Border>
    </DataTemplate>
    <Common:CustomSampleDataTemplateSelector x:Key="mySelector"
                                     FirstDataTemplate="{StaticResource myTemplate1}"
                                     SecondDataTemplate="{StaticResource myTemplate2}">
    </Common:CustomSampleDataTemplateSelector >
</UserControl.Resources>

Use it

<GridView  x:Name="PicturesGridView" ItemTemplateSelector="{StaticResource mySelector}">

That's all

like image 60
Ivan Fioravanti Avatar answered Oct 29 '22 07:10

Ivan Fioravanti


Thank you. It actually works well because it makes the first item having a different template than the other. However it was not what I wanted sorry it's my fault I wasn't clear. Because with your technique the item size in the grid view has always the same size. Let's say I choose myTemplate1 to have a grid with a width of 400 and myTemplate2 a grid with a width of 200. Then if my first element follows myTemplate1, all the element of the grid view will have a size of 400 even if the image inside is only 200.

I wanted to achieve a result like in this article : http://blogs.u2u.be/diederik/post/2012/03/07/Databinding-to-the-VariableSizedWrapGrid-in-Windows-8-Metro.aspx

So I found what I actually needed it's VariableSizedWrapGrid and to reimplement a version of a gridView.I Followed this very good article : http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/966aa897-1413-46f0-bef7-663de36f9423.

However I'll mark your answer as correct because it answer my initial question : it allows to select different item size in a group grid view.

Thank you very much for your time it helped me a lot

like image 43
Thomas Salandre Avatar answered Oct 29 '22 07:10

Thomas Salandre