locked
Grouped GridView 2 problems RRS feed

  • Question

  • Hello. I have app with grouped GridView, and i notice 2 problems. First problem is probably bug.

    1) - lets make grouped gridview, hideifempty group property is default false. Now bind to it grouped CollectionViewSource with 5 empty groups. Run app, nothing happen, gridview is empty, label of groups didnt show.

     - now add one item to 3 group. Label of first group is shown. Third group is not showing at all

     - now add second item to 3 group. Label of first and second group is shown. Third group is not showing at all

     - now add third item to 3 group. Label of first, second and third group is shown. All 3 items of third group is showing

     - now add 4th item to 3 group. Look like 3 step+4th label appear

    So, my conclusion is, displaying groups is someting like this: for(int i = 0; i<items.Count();i++). Shouldnt it be based on group count? for(int i = 0; i<group.Count();i++). For me its serious bug. User must add 5 items to gridview to see 5th group...

    I dont know how this works in RP, but i hope RTM can be still patched...

    2)RESOLVED Second problem is question. When i set source of GridView like this: myGridView.ItemsSource = SomeList; all is good. But becouse i have grouped gridview, i must use CVS. So: myGridView.ItemsSource = myCVS; myCVS.Source = SomeList; When doing it this way, dont know why, but first item is selected. Other topics on this forums confirm this problem. As a temporary solution, people suggest Loaded event and (sender as GridView).SelectedItem = null;

    But, myGridView is part of FlipView controll. When itemspanel of FlipView is StackPanel, all works fine. But when i change it to VirtualizingStackPanel, loaded event is fired only for first 2 myGridView. When user flip to third item, its myGridView still have first item selected.

    How to make it working? Maybe some other event? Loaded event is fire when app start, not when item is created to shown on screen.



    • Edited by raximus Tuesday, August 21, 2012 4:48 PM
    Monday, August 20, 2012 12:01 PM

Answers

  • After you wrote in my thread, i think about this problem one more time.

    And i find a solution ;)

    Just change ItemsPanel from StackPanel to <VirtualizingStackPanel Orientation="Horizontal"/>. Then it will show all groups even with 1 item. But another problem will show on, scrolling will be f.ck up, but its easy to solve, put GridView in ScrollViewer.

    This way you help me, I hope I help You too ;)

    Saturday, March 30, 2013 4:11 PM

All replies

  • Q2: "When doing it this way, dont know why, but first item is selected": you can avoid this by binding to the 'ItemsList' itself, not its CVS.
    Monday, August 20, 2012 12:32 PM
  • But myGridView is grouped, so i must use grouped CVS.
    Monday, August 20, 2012 12:33 PM
  • Correct ! However, when I bind to a code-behind made CVS, I don't have the annoying Selection. I haven't tried it in your scenario [*] but here is a small view-model sample:

    public class KiwiExec : INotifyPropertyChanged
        {
            #region Events
            public event PropertyChangedEventHandler PropertyChanged;
    
            private void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
            #endregion
            #region Underlying collection
            private ObservableCollection<KiwiItem> itemList = new ObservableCollection<KiwiItem>();
            public ObservableCollection<KiwiItem> ItemList
            {
                get { return itemList; }
                set
                {
                    itemList = value;
                    OnPropertyChanged("ItemList");
                }
            }
            #endregion
            #region Collection view & Current
            private CollectionViewSource viewSource;
            public ICollectionView View
            {
                get
                {
                    if (viewSource == null)
                    {
                        viewSource = new CollectionViewSource();
                        viewSource.Source = ItemList;
                        viewSource.View.CurrentChanged += View_CurrentChanged;
                    }
                    return viewSource.View;
                }
            }
            void View_CurrentChanged(object sender, object e)
            {
                Current = this.View.CurrentItem as KiwiItem;
            }
            private KiwiItem current;
            public KiwiItem Current
            {
                get { return current; }
                set
                {
                    current = value;
                    OnPropertyChanged("Current");
                }
            }
            #endregion
         }

    ---
    My XAML binding is then : ItemsSource = "{Binding View}" instead of "{Binding ItemList}"
    ---
    [*]: You would have to add 'viewSource.IsSourceGrouped = true;' or other properties you'd have in your XAML equivalent 


    • Edited by ForInfo Monday, August 20, 2012 1:21 PM
    Monday, August 20, 2012 1:15 PM
  • ForInfo, thx for Your code, but it didnt work. Did you test your code on RTM? Or maybe grouping is problem.

    But, back to my 2 problems, i made a repro to this 2 problems. Whats strange, first problem only appear on GridView, when i made a ListView, all works fine. But i need grouped GridView...

    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Navigation;
    
    namespace Test
    {
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                Projects Projects = new Projects();
    
                Project newProject = new Project();
                newProject.Name = "Project 1";
                //newProject.Add(new Activity() { Name = "Activity 1" });
                //newProject.Add(new Activity() { Name = "Activity 2" });
                Projects.Add(newProject);
    
                newProject = new Project();
                newProject.Name = "Project 2";
                newProject.Add(new Activity() { Name = "Activity A" });
                //newProject.Add(new Activity() { Name = "Activity B" });
                Projects.Add(newProject);
    
                newProject = new Project();
                newProject.Name = "Project 3";
                //newProject.Add(new Activity() { Name = "Activity X" });
                //newProject.Add(new Activity() { Name = "Activity Y" });
                Projects.Add(newProject);
    
                gridView.ItemsSource = Projects.View;
                listView.ItemsSource = Projects.View;
            }      
        }
    
        public class Projects : ObservableCollection<Project>
        {
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
    
            private CollectionViewSource viewSource;
            public ICollectionView View
            {
                get
                {
                    if (viewSource == null)
                    {
                        viewSource = new CollectionViewSource();
                        viewSource.IsSourceGrouped = true;
                        viewSource.Source = this;
                        viewSource.View.CurrentChanged += View_CurrentChanged;
                    }
                    return viewSource.View;
                }
            }
    
            void View_CurrentChanged(object sender, object e)
            {
                Current = this.View.CurrentItem as Activity;
            }
            private Activity current;
            public Activity Current
            {
                get { return current; }
                set
                {
                    current = value;
                    OnPropertyChanged("Current");
                }
            }
        }
        public class Project : ObservableCollection<Activity>
        {
            public string Name { get; set; }
        }
        public class Activity
        {
            public string Name { get; set; }
        }
    
    }
    

    <Page
        x:Class="Test.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Test"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <!--<UserControl.Resources>
            <CollectionViewSource x:Name="cvsProjects" IsSourceGrouped="True"/>
        </UserControl.Resources>-->
        
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
    
            <GridView x:Name="gridView" Grid.Column="0" Background="Gray">
                <GridView.ItemTemplate>
                    <DataTemplate>
                        <Grid Width="300" Height="300">
                            <TextBlock Text="{Binding Name}" FontWeight="Bold" Style="{StaticResource ItemTextStyle}"/>
                        </Grid>
                    </DataTemplate>
                </GridView.ItemTemplate>
    
                <GridView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </GridView.ItemsPanel>
    
                <GridView.GroupStyle>
                    <GroupStyle>
                        <GroupStyle.HeaderTemplate>
                            <DataTemplate>
                                <TextBlock Text='{Binding Name}' Foreground="Black" Margin="10" Style="{StaticResource PageSubheaderTextStyle}" />
                            </DataTemplate>
                        </GroupStyle.HeaderTemplate>
    
                        <GroupStyle.Panel>
                            <ItemsPanelTemplate>
                                <StackPanel Orientation="Vertical"/>
                            </ItemsPanelTemplate>
                        </GroupStyle.Panel>
                    </GroupStyle>
                </GridView.GroupStyle>
            </GridView>
            
            <ListView x:Name="listView" Grid.Column="1" Margin="50" Background="Gray">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Grid Width="300" Height="300">
                            <TextBlock Text="{Binding Name}" FontWeight="Bold" Style="{StaticResource ItemTextStyle}"/>
                        </Grid>
                    </DataTemplate>
                </ListView.ItemTemplate>
    
                <!--<ListView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Vertical"/>
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>-->
    
                <ListView.GroupStyle>
                    <GroupStyle>
                        <GroupStyle.HeaderTemplate>
                            <DataTemplate>
                                <TextBlock Text='{Binding Name}' Foreground="Black" Margin="10" Style="{StaticResource PageSubheaderTextStyle}" />
                            </DataTemplate>
                        </GroupStyle.HeaderTemplate>
    
                        <GroupStyle.Panel>
                            <ItemsPanelTemplate>
                                <StackPanel Orientation="Vertical"/>
                            </ItemsPanelTemplate>
                        </GroupStyle.Panel>
                    </GroupStyle>
                </ListView.GroupStyle>
            </ListView>
        </Grid>
    </Page>
    
    
    
    As we see on picture, i add first empty group, secodn with 1 item, and third empty. On ListView all looks fine, on GridView, 1 item = 1 group, 2 items = 2 groups, 3 items = 3 groups...
    Tuesday, August 21, 2012 8:08 AM
  • Raximus, thank you for your code. In RTM, it allowed me to identify [I think] an additional condition to solve problem # 2:

    <GridView x:Name="gridView" Grid.Column="0" Background="Gray" IsSynchronizedWithCurrentItem="{x:Null}">

    ---

    Could you test this option ?
    ---

    In order to get rid of the default Selection mechanism [GridView or ListView, Grouped or not] it would appear that:

    1.- CVS must be declared in code-behind
    2.- IsSynchronizedWithCurrentItem="{x:Null}" must be set



    • Edited by ForInfo Tuesday, August 21, 2012 1:01 PM
    Tuesday, August 21, 2012 12:47 PM
  • Thx ForInfo!! Now it works. I will mark Your post as Answer when someone help me with first problem.

    So, first problem still exist. If gridview not work and listview work, i think it can be bug. If i am wrong, and i can be resolved, will be cool if someone help me with this. My app will be in store in 1-2 days.

    Tuesday, August 21, 2012 4:46 PM
  • Raximus - did you test this on RTM?

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Friday, August 24, 2012 6:52 PM
    Moderator
  • Yes. My app is already in store. As i said, my app have this bug, code i shown in my 3 post have this bug, and even official Ms sample called "grouped gridview" have this bug. It didnt show default becouse sample have more items than groups. Change sample source to 3 groups and 2 items and you will see. And as i said, on listview all works fine.
    Friday, August 24, 2012 9:10 PM
  • I am waiting 9 days, 7 days my app is in Store. Are noone can help me?

    Wednesday, August 29, 2012 8:24 PM
  • I have the exact same problem as #1, were you able to fix this?
    Does anyone have a solution?

    Thursday, March 28, 2013 7:31 PM
  • After 7 months, i am still fighting with this BUG. And 0 help from MSFT :(

    I made reproduction solution: https://skydrive.live.com/redir?resid=3ACC980B2415E414!354&authkey=!ALyhkxHTjLI0rjc

    Friday, March 29, 2013 7:21 PM
  • After you wrote in my thread, i think about this problem one more time.

    And i find a solution ;)

    Just change ItemsPanel from StackPanel to <VirtualizingStackPanel Orientation="Horizontal"/>. Then it will show all groups even with 1 item. But another problem will show on, scrolling will be f.ck up, but its easy to solve, put GridView in ScrollViewer.

    This way you help me, I hope I help You too ;)

    Saturday, March 30, 2013 4:11 PM