W8 Store App Gridview Binding - c#

I'm new to using MVVM and I'm having some problems that I think may just require me to flatten data, but I hate to do that if there is a better way. I have the GroupedItemsPage that VS 2013 sticks into the project and I have bound my list to it, and my group names show up fine, but I haven't figured out how to do the items in the group. I have bound my GridView to List and each group has a List in it that contains all the items for that group.
<CollectionViewSource
x:Name="groupedItemsViewSource"
Source="{Binding Groups}"
IsSourceGrouped="true"
ItemsPath="Items"
d:Source="{Binding Groups}"/>
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
Grid.RowSpan="2"
Padding="116,137,40,46"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick">
<GridView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}">
<Image Source="{Binding ImageID}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Name}"/>
</Border>
<StackPanel VerticalAlignment="Bottom" Background="{ThemeResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding Name}" Foreground="{ThemeResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextBlockStyle}" Height="60" Margin="15,0,15,0"/>
<TextBlock Text="{Binding Description}" Foreground="{ThemeResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid GroupPadding="0,0,70,0"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="0,0,0,2">
<Button Foreground="{ThemeResource ApplicationHeaderForegroundThemeBrush}"
AutomationProperties.Name="Group Title"
Style="{StaticResource TextBlockButtonStyle}" >
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" Margin="0,-11,10,10" Style="{StaticResource SubheaderTextBlockStyle}" TextWrapping="NoWrap" />
<TextBlock Text="{StaticResource ChevronGlyph}" FontFamily="Segoe UI Symbol" Margin="0,-11,0,10" Style="{StaticResource SubheaderTextBlockStyle}" TextWrapping="NoWrap" />
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
public class Group
{
public string Name {get;set;}
public List<Item> Items {get;set;}
}
public class Item
{
public string Name {get;set;}
public string Description {get;set;}
public Guid ImageID {get;set;}
}
I spend a couple hours searching last night without luck, though that may be not knowing what I need to find. The default code from MS has a ton of stuff in it, so I tried to thin it down to what I think are the relevant parts.

Related

Wpf Binding Dicionaly with key and list on objects to ListView [duplicate]

I have a Dictionary<string, List<WritingMachine>> where the key is the hostname of a machine that writes to a server, and the value is an list of WritingMachine objects (shown below):
public class WritingMachine
{
public string HostName { get; set; }
public string Program { get; set; }
public string Login { get; set; }
public string Server { get; set; }
}
I'm trying to bind the dictionary to a WPF ListBox; displaying the Hostname (the dictionary's key), and a summary of the WritingMachine list that's associated with that key.
I'm having trouble accessing the properties of the individual WritingMachine elements within the list.
Here's my XAML so far:
<ListBox x:Name="MachineListBox" Margin="10" Grid.Column="0" FontFamily="Consolas" ItemsSource="{Binding Path=MachineDictionary}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Margin="5">
<ContentPresenter Content="{Binding Key}" Margin="0,0,4,0"/>
<ItemsControl ItemsSource="{Binding Value}" Margin="10,0,0,0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
This results in a listbox that looks like this:
Obviously this is wrong because the WritingMachine list elements are just returning the default ToString. By overriding WritingMachine's ToString I can get the effect I want (more or less):
But this a crap way of doing it... I want to be able to access the individual element properties and arrange them in controls in my ListBox.ItemTemplate using Content="{Binding Value.Server}" or similar.
Any ideas?
For your ItemsControl you need to set an ItemTemplate:
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock>Server: </TextBlock>
<TextBlock Text="{Binding Server}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
That will get you started.
Set DataContext property for inner control to show WritingMachine properties.
Like so :
<StackPanel DataContext="{Binding Value}" Grid.Row="1">
This will change the DataContext to List<WritingMachine> for inner display control, where you can do normal binding. See full XAML code below :
<ListBox x:Name="LbxMachineDictionary" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Margin="5">
<Grid Width="461" Height="199">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="4*"/>
</Grid.RowDefinitions>
<TextBlock HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="{Binding Key}" VerticalAlignment="Top"/>
<StackPanel DataContext="{Binding Value}" Grid.Row="1">
<TextBlock HorizontalAlignment="Left" Grid.Row="1" TextWrapping="Wrap" Text="{Binding HostName}" VerticalAlignment="Top"/>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Program}" VerticalAlignment="Top"/>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Login}" VerticalAlignment="Top"/>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Server}" VerticalAlignment="Top"/>
</StackPanel>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Windows 8 metro app: Accessing the button property

I am new to windows 8.1 development.
I created the pages below with the button on the xaml page
GroupedItemsPage.xaml.cs
GroupedItemsPage.xaml
<Button Style="{StaticResource mystyle}" Click="ItemView_ItemClick" x:Name="Testing">
I was thinking that on page load of the xaml page I will be able to have access to the button property
by doing something like this .. Testing.property as we normally do in the windows development environment. This is not happening. I want to be able to style some buttons programmatically.
How can I get the property of the button in the .cs file?
Thanks. Here is the xaml page below.
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
Grid.RowSpan="2"
Padding="116,137,40,46"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
SelectionMode="None"
IsSwipeEnabled="false"
>
<GridView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Width="Auto" Height="Auto" >
<Image Source="{Binding ImagePath}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
</Border>
<StackPanel VerticalAlignment="Bottom" Background="{ThemeResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding Title}" Foreground="{ThemeResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextBlockStyle}" Height="60" Margin="15,0,15,0"/>
<TextBlock Text="{Binding Subtitle}" Foreground="{ThemeResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>-->
<Button Style="{StaticResource contactSquarePref}" Click="ItemView_ItemClick" x:Name="Testing">
<StackPanel Margin="5" >
<TextBlock Tag="cntCustName" Style="{ThemeResource CntNormalTextBlockStyle}" Text="{Binding Name }"/>
<TextBlock Tag="cntCatCode" Style="{ThemeResource CntLrgTextBlockStyle}" Text="{Binding Address}"/>
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid GroupPadding="0,0,70,0"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="0,0,0,2">
<Button Foreground="{ThemeResource ApplicationHeaderForegroundThemeBrush}"
AutomationProperties.Name="Group Title"
Click="Header_Click"
Style="{StaticResource TextBlockButtonStyle}" >
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ContactType}" Margin="0,-11,10,10" Style="{StaticResource SubheaderTextBlockStyle}" TextWrapping="NoWrap" />
<TextBlock Text="{StaticResource ChevronGlyph}" FontFamily="Segoe UI Symbol" Margin="0,-11,0,10" Style="{StaticResource SubheaderTextBlockStyle}" TextWrapping="NoWrap" />
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
It depends on your XAML. If your button is just a child element (i.e. part of your logical tree) or a named resource of your page, there'll be no problem, there's a code generation process on build, that creates required fields (in this case Button Testing) and finds required elements in InitializeComponent() generated method.
But if your button is a part of control template the only way to get reference to your element is GetTemplateChild() (if you're writing your own control, as this method is protected) or manually observing Visual Tree.
So, if you have a problem with the child element of your page, past all of your XAML markup here, as the line in the question above is not enough to find solution. But if you've defined button in control template, look at the second paragraph.

Multi-column stackpanel or alternative

I have the following XAML code:
<StackPanel Background="White" Margin="267,207,0,44" Grid.ColumnSpan="2">
<ScrollViewer Margin="30,30,0,30" Height="444">
<ItemsControl Name="ListCountries">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,10,0" Width="100">
<TextBlock Text="{Binding Key}" Foreground="Red" />
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,10,0,0">
<TextBlock TextWrapping="Wrap" Text="{Binding title}" Foreground="Black" />
<TextBlock TextWrapping="Wrap" Text="{Binding desc}" Foreground="Gray" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>
I set the itemSource of the itemsControl named ListCountries, with a IEnumerable> and it prints a list of titles, followed by a list of objects of the OtherClass.
My problem is that , the columns that are filled sometimes are bigger than the height of the Stackpanel that they are inserted to, i want to be able to split my inner list of into columns.
as you can see in the image, Belgium country gets splited into 2 columns
right now all my countries are single column with vertical scroll.
You should use a GridView for this. Here's some code slightly modified from a Grid app in Visual Studio
<GridView
x:Name="itemGridView"
Grid.RowSpan="2"
Padding="116,137,40,46"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
SelectionMode="None"
Height="600">
<GridView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Width="200">
<TextBlock Text="{Binding Description}" Foreground="{ThemeResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextBlockStyle}" Height="60" Margin="15,0,15,0"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}" Style="{StaticResource SubheaderTextBlockStyle}" TextWrapping="NoWrap" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
Here's a screenshot of what this looks like, with sample data

LongListSelector's performance is very bad. How to improve?

here is my code
<phone:LongListSelector ItemsSource="{Binding MovieTimeInDetailItems}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Margin="24,0,0,12">
<TextBlock Text="{Binding Theater}" FontSize="34"/>
<ListBox ItemsSource="{Binding TimeItems}" HorizontalAlignment="Stretch" VerticalAlignment="Top" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Width="115" Margin="0,0,0,0">
<TextBlock Text="{Binding Time}"
TextWrapping="Wrap"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontSize="26"
Foreground="{StaticResource PhoneSubtleBrush}"/>
<Border Margin="92,0,0,0" HorizontalAlignment="Left" Width="{Binding Width}" Height="25" BorderThickness="1.5,0,0,0" BorderBrush="{StaticResource PhoneSubtleBrush}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
In each LLS item contains a Listbox which display time list.
my question is ...
Can I display a time list without Listbox ? It seems Listbox cause the low performance.

Binding design time data collections in Blend 2013 for Windows Store App

I'll try and provide as much information here as possible but let me prefix it by saying I'm not confident of my knowledge of regular data sources never mind design time data in Blend. My runtime works fine and displays grouped items in the grid view. When viewing in Blend I get nothing and I would like to display some sample data that does the same as the runtime. Is it possible to achieve this? Also if I've gone wrong and over complicated the runtime data sources please feel free to suggest changes.
<common:LayoutAwarePage
x:Name="pageRoot"
x:Class="ScoreAlerts.ItemsPage"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
...snip...>
<CollectionViewSource
x:Name="itemsViewSource"
IsSourceGrouped="true"
Source="{Binding Items}"/>
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemsGridView"
AutomationProperties.Name="Items"
TabIndex="1"
Grid.RowSpan="2"
Padding="116,136,116,46"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick" FontFamily="Global User Interface" FontWeight="Light" Margin="0,0,10,0">
<GridView.Resources>
<!-- Grid-appropriate 250 pixel square item template as seen in the GroupedItemsPage and ItemsPage -->
<DataTemplate x:Key="GridItem">
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border Background="{x:Null}">
<Image Source="{Binding Image}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
</Border>
<StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding Title}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0"/>
<!-- <TextBlock Text="{Binding Subtitle}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/> -->
</StackPanel>
</Grid>
</DataTemplate>
</GridView.Resources>
<GridView.ItemsSource>
<Binding Source="{StaticResource itemsViewSource}"/>
</GridView.ItemsSource>
<!-- Item Template -->
<GridView.ItemTemplate>
<StaticResource ResourceKey="GridItem"/>
</GridView.ItemTemplate>
<!-- Item Panel Template -->
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid MaximumRowsOrColumns="4"
HorizontalAlignment="Left"
VerticalAlignment="Center" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="0">
<TextBlock Text="{Binding Key}"
Style="{StaticResource PageSubheaderTextStyle}"
Margin="8 4 0 10" />
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Vertical" Margin="0 0 40 0"/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
in the code I have this
this.DefaultViewModel["Items"] = ScoreDataSource.GetGroups("AllGroups")
And my ScoreDataSource has the following
public sealed class ScoreDataSource
{
public static ScoreDataSource _ScoreDataSource = new ScoreDataSource();
private ObservableCollection<ScoreDataGroup> _allGroups = new ObservableCollection<ScoreDataGroup>();
public ObservableCollection<ScoreDataGroup> AllGroups
{
get { return this._allGroups; }
}
public static IEnumerable<object> GetGroups(string uniqueId)
{
if ( uniqueId == "AllGroups" )
{
var query = from item in _ScoreDataSource.AllGroups
orderby item.Country
group item by item.Country into g
select g;
return query;
}
else
{
return _ScoreDataSource.AllGroups;
}
}

Categories

Resources