Bitsian
Bitsian

Reputation: 2258

Grouping items on a grid view

I have alarm model objects which have a Repeat collection containing the days the alarm should repeat. I want to display the alarms in a grid view grouped under the day of the week(like monday,tuesday etc).

And i am adding all these alarms into a collection "Alarms"

For each alarm in alarms, I am again creating alarms for each day in the repeat collection of the alarm and adding them all to a collection "TotalAlarms".

foreach (Alarm alarm in this.Config.Alarms)
        {
            foreach (DayOfWeek day in alarm.Repeat)
            {
                this.tempAlarm = this.CopyAlarm(alarm);

                tempAlarm.DayOfWeek = day;                 

                TotalAlarms.Add(tempAlarm);
            }
        }

And am using linq to group on the DayOfWeek property of alarm model which indicates the day on which the alarm should go off.

var result = from t in _ViewModel.TotalAlarms
                     group t by  t.DayOfWeek into q                        
                     orderby q.Key
                     select q;

And am adding this result to the groupedItemsViewSource (binding to itemsource of grid view)

groupedItemsViewSource.Source = result;

and for the header of the grid view, am binding it to "Key"

<TextBlock Text="{Binding Key}" Style="{StaticResource TitleTextStyle}" FontSize="20" HorizontalAlignment="Stretch" VerticalAlignment="Center" Width="100" Height="30" Margin="5"/>

This approach displays only the days of week for which there is an alarm. Like if the alarms are set to friday and saturday, only friday and saturday are shown in the group headers.

What i want is all the days beings shown as group headers and if there are no alarms for that day then it can be empty. But the group headers should display all days.

I am really finding it hard to think of a way to do that. If anyone has any idea, please help me out here....

Thanks

Upvotes: 4

Views: 2331

Answers (3)

FatemehEbrahimiNik
FatemehEbrahimiNik

Reputation: 613

I use this one for my project

Note: i want to group by one of fields of my table

My model is:

 public class Item : INotifyPropertyChanged
    {
        public Item()
        {
        }
        public event PropertyChangedEventHandler PropertyChanged;
        private string _name;
        public string name { set { _name = value; OnPropertyChanged("name"); } get { return _name; } }
        private string _color;
        public string color { set { _color = value; OnPropertyChanged("color"); } get { return _color; } }
        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }

    }

in xaml gridview is:

<GridView x:Name="gr" SelectionChanged="gr_SelectionChanged"  ItemsSource="{Binding Source={StaticResource CollectionViewSource}}" Margin="-400,30,0,0" SelectionMode="Multiple" SelectedValuePath="{Binding selectedItemFalg, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
                <GridView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <ItemsWrapGrid Orientation="Horizontal" Width="500" />
                    </ItemsPanelTemplate>
                </GridView.ItemsPanel>
                <GridView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal"  Background="#FFD7EDF2" Margin="0,0,0,0" Width="80">
                            <TextBlock Text="{Binding name}" Foreground="#FF00455A"  Margin="5,5,0,0"  Height="30" />
                            <TextBlock Text="-" Foreground="#FF00455A"  Margin="5,5,0,0"  Height="30" />
                            <TextBlock Text="{Binding color}" Foreground="#FF00455A"  Margin="5,5,0,0"  Height="30" />
                        </StackPanel>
                    </DataTemplate>
                </GridView.ItemTemplate>
                <GridView.GroupStyle>
                    <GroupStyle>
                        <GroupStyle.HeaderTemplate>
                            <DataTemplate>
                                <Grid Background="Blue" Margin="10">
                                    <TextBlock Text='{Binding Key}' Foreground="Black" FontSize="25" Margin="5" Width="80"/>
                                </Grid>
                            </DataTemplate>
                        </GroupStyle.HeaderTemplate>
                    </GroupStyle>
                </GridView.GroupStyle>
            </GridView>

And in viewModel need this code:

 public  class date_for_my_page
    {
       public date_for_my_page()
       {
           Item item = new Item();
           item.color = "black1";
           item.name = "A";
           Collection.Add(item);
           item = new Item();
           item.color = "black2";
           item.name = "A";
           Collection.Add(item);
           item = new Item();
           item.color = "black3";
           item.name = "A";
           Collection.Add(item);
           item = new Item();
           item.color = "black4";
           item.name = "A";
           Collection.Add(item);
           item = new Item();
           item.color = "black5";
           item.name = "A";
           Collection.Add(item);
           item = new Item();
           item.color = "blue1";
           item.name = "B";
           Collection.Add(item);
           item = new Item();
           item.color = "blue2";
           item.name = "B";
           Collection.Add(item);
           item = new Item();
           item.color = "blue3";
           item.name = "B";
           Collection.Add(item);
           item = new Item();
           item.color = "Red1";
           item.name = "C";
           Collection.Add(item);
           item = new Item();
           item.color = "Red2";
           item.name = "C";
           Collection.Add(item);
       }
        private ItemCollection _Collection = new ItemCollection();

        public ItemCollection Collection
        {
            get
            {
                return this._Collection;
            }
        }

        internal List<GroupInfoList<object>> GetGroupsByCategory()
        {
            List<GroupInfoList<object>> groups = new List<GroupInfoList<object>>();

            var query = from item in Collection
                        orderby ((Item)item).name
                        group item by ((Item)item).name into g
                        select new { GroupName = g.Key, Items = g };
            foreach (var g in query)
            {
                GroupInfoList<object> info = new GroupInfoList<object>();
                info.Key = g.GroupName;
                foreach (var item in g.Items)
                {
                    info.Add(item);
                }
                groups.Add(info);
            }

            return groups;

        }

    }
   public class ItemCollection : IEnumerable<Object>
   {
       private System.Collections.ObjectModel.ObservableCollection<Item> itemCollection = new System.Collections.ObjectModel.ObservableCollection<Item>();

       public IEnumerator<Object> GetEnumerator()
       {
           return itemCollection.GetEnumerator();
       }

       System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
       {
           return GetEnumerator();
       }

       public void Add(Item item)
       {
           itemCollection.Add(item);
       }
   }
   public class GroupInfoList<T> : List<object>
   {

       public object Key { get; set; }


       public new IEnumerator<object> GetEnumerator()
       {
           return (System.Collections.Generic.IEnumerator<object>)base.GetEnumerator();
       }
   }

At the last i want to bind my sorted data to my gridView

date_for_my_page _date = new date_for_my_page();
List<GroupInfoList<object>> sort_data = _date.GetGroupsByCategory();
CollectionViewSource.Source = sort_data;

Output will show this:

enter image description here Hope this helped to all.

Upvotes: 0

Bitsian
Bitsian

Reputation: 2258

I finally figured out the answer myself. Its a bit messy and ugly but it works. I use 7 grid views now instead of one. But it still doesnt show the header unless there is a data item in the grid view. SO if the grid view collection is empty then i add some empty object to the collection binding the grid view and then i reduce the height of the grid view so that the empty item is not displayed and only the header is displayed.

This is the sample code for one grid view.

 emptyAlarmsList = new ObservableCollection<Alarm>();
        emptyAlarmsList.Add(new Alarm());

        var sundayAlarms = from t in _ViewModel.TotalAlarms
                           where t.DayOfWeek == DayOfWeek.Sunday
                           group t by t.DayOfWeek into g
                           orderby g.Key
                           select g;

        if (sundayAlarms.Count() == 0)
        {
            var sundayEmptyAlarms = from t in this.emptyAlarmsList                                   
                               group t by t.DayOfWeek into g
                               orderby g.Key
                               select g;
            SundayAlarmsView.Source = sundayEmptyAlarms;
            itemGridView1.VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Top;
            itemGridView1.Height = 100;
        }
        else
            SundayAlarmsView.Source = sundayAlarms;

And the XAMl code for one grid view

 <CollectionViewSource
        x:Name="SundayAlarmsView"            
        IsSourceGrouped="true"
        />
            <GridView
        x:Name="itemGridView1"
        AutomationProperties.AutomationId="ItemGridView1"
        AutomationProperties.Name="Grouped Items"            
        Grid.Column="0"
        Margin="0,-3,0,0"
        Padding="116,0,40,46"
        SelectionMode= "Extended"
        ItemsSource="{Binding Source={StaticResource SundayAlarmsView}}"
        ItemTemplate="{StaticResource AlarmListTemplate}"
        SelectionChanged="Alarm_SelectionChanged">

                <GridView.ItemContainerStyle>
                    <Style
                TargetType="GridViewItem">
                        <Setter
                    Property="Height"
                    Value="150" />
                        <Setter
                    Property="Width"
                    Value="250" />
                        <Setter
                    Property="Margin"
                    Value="10,10" />
                    </Style>
                </GridView.ItemContainerStyle>

                <GridView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </GridView.ItemsPanel>
                <GridView.GroupStyle>
                    <GroupStyle>
                        <GroupStyle.HeaderTemplate>
                            <DataTemplate>

                                <TextBlock Text="Sunday" Style="{StaticResource TitleTextStyle}" FontSize="20" HorizontalAlignment="Stretch" VerticalAlignment="Center" Width="100" Height="30" Margin="5"/>

                            </DataTemplate>
                        </GroupStyle.HeaderTemplate>
                        <GroupStyle.Panel>
                            <ItemsPanelTemplate>
                                <VariableSizedWrapGrid Orientation="Vertical" Margin="0,0,80,0"/>
                            </ItemsPanelTemplate>
                        </GroupStyle.Panel>
                    </GroupStyle>
                </GridView.GroupStyle>
            </GridView>

Upvotes: 0

The Goat
The Goat

Reputation: 1090

Look at this articles: http://code.msdn.microsoft.com/windowsapps/Push-and-periodic-de225603

http://msdn.microsoft.com/en-us/library/windows/apps/xaml/Hh868244(v=win.10).aspx

Push notifications, is can be periodically or a special condition.

Upvotes: 0

Related Questions