Reputation: 2258
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
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:
Upvotes: 0
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
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