Issue with binding itemsource using MVVM in WP7 - windows-phone-7

I am using MVVM pattern and I am trying to bind a public ObservableCollection Friends property to LongListSelector
<toolkit:LongListSelector
ItemsSource="{Binding Friends}"
GroupHeaderTemplate="{StaticResource movieGroupHeader}"
ListHeaderTemplate="{StaticResource movieListHeader}">
<toolkit:LongListSelector.ItemTemplate>
<DataTemplate>
<Grid Margin="12,8,0,8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" VerticalAlignment="Top">
<TextBlock Text="{Binding MyBoxName}" Style="{StaticResource PhoneTextLargeStyle}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" Margin="12,-12,12,6"/>
<TextBlock Text="{Binding MyBoxID}" Style="{StaticResource PhoneTextNormalStyle}" TextWrapping="Wrap" FontFamily="{StaticResource PhoneFontFamilySemiBold}"/>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Status:" Style="{StaticResource PhoneTextSmallStyle}"/>
<TextBlock Text="{Binding Status}" Style="{StaticResource PhoneTextSmallStyle}" FontFamily="{StaticResource PhoneFontFamilySemiBold}"/>
</StackPanel>
</StackPanel>
</Grid>
</DataTemplate>
</toolkit:LongListSelector.ItemTemplate>
</toolkit:LongListSelector>
Now issues is when i try to add
_friends.Add(new Model.Friends
{
MyBoxID = e.RosterItem.Jid,
MyBoxName = e.RosterItem.Name,
Status = Matrix.Xmpp.PresenceType.unavailable
})
it gives InvalidCastException so i tried List instead of ObservableCollection. Now i don't get exception but nothing is displayed in LLS. How can i bind My ObservableCollection property to LLS with Grouping.

For LongListSelector you need not just a collection, but some more complex structure to support grouping
Look at LongListCollection. It's great class that should help you
Usage:
var list = new LongListCollection<Event, string>(Events, x => x.Date.ToLongDateString());

Related

Windows 8 - XAML - Conditional background for row in ListView

I have a data source with items in it. Each item has a boolean called "IsAvailable".
I want to render the datasource in a ListView. The background of each row must be green if "IsAvailable" = true or red if "IsAvailable" = false.
How can I do it?
Thanks
-- Marco
This is the code:
<ListView x:Name="frItemlistView" Margin="10,40,666,10" SelectionMode="None" ItemsSource="{Binding Source={StaticResource availableItemsViewSource}}" IsSwipeEnabled="false" IsItemClickEnabled="True" ItemClick="frItemlistView_ItemClick_1" Grid.Row="1" DoubleTapped="frItemlistView_DoubleTapped_1" RightTapped="frItemlistView_RightTapped_1" BorderThickness="35,0,35,35" Grid.RowSpan="2">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="110" Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,0,0,0">
<TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextStyle}" TextWrapping="NoWrap"/>
<TextBlock Text="{Binding Subtitle}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/>
<TextBlock Text="{Binding Volume}" Style="{StaticResource BodyTextStyle}" MaxHeight="60"/>
<TextBlock Text="{Binding IsAvailable}" Style="{StaticResource BodyTextStyle}" MaxHeight="60" />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You can use converter to do conditional formatting of DataTemplate. You need to bind IsAvailable property to background of StackPanel, converter will give appropriate color.
Add a class with this definition.
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media;
using Windows.UI;
public class AvailabilityToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var Availability = (bool)value;
var color = Availability ? new SolidColorBrush(Colors.Green) : new SolidColorBrush(Colors.Red);
return color;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
XAML
local is the XAML namespace reference of AvailabilityToColorConverter class, which is in <Page />
<Page.Resources>
<local:AvailabilityToColorConverter x:Key="AvailabilityToColor" />
</Page.Resources>
<ListView x:Name="frItemlistView" Margin="10,40,666,10" SelectionMode="None" ItemsSource="{Binding Source={StaticResource availableItemsViewSource}}" IsSwipeEnabled="false" IsItemClickEnabled="True" ItemClick="frItemlistView_ItemClick_1" Grid.Row="1" DoubleTapped="frItemlistView_DoubleTapped_1" RightTapped="frItemlistView_RightTapped_1" BorderThickness="35,0,35,35" Grid.RowSpan="2">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="110" Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,0,0,0" Background="{Binding IsAvailable, Converter={StaticResource AvailabilityToColor}}">
<TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextStyle}" TextWrapping="NoWrap"/>
<TextBlock Text="{Binding Subtitle}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap"/>
<TextBlock Text="{Binding Volume}" Style="{StaticResource BodyTextStyle}" MaxHeight="60"/>
<TextBlock Text="{Binding IsAvailable}" Style="{StaticResource BodyTextStyle}" MaxHeight="60" />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

How to bind data in gridview format in windows phone?

Hi i am developing windows phone 8 app.i want to display image on grid view format and i am using listbox inside grid but i didn't get any changes in my output.my code is given below,I want display data on grid view format.
<Grid x:Name="ContentPanel" Margin="0,115,0,0" Background="#424340" Grid.RowSpan="5" />
<StackPanel Margin="0,0,0,0.083" Grid.Row="2" VerticalAlignment="Top" HorizontalAlignment="Center" Grid.RowSpan="2">
<ListBox x:Name="List12" ItemsSource="{Binding}" VerticalAlignment="Top" SelectionChanged="NotchsList12_SelectionChanged"
Margin="0,0,0,0" HorizontalAlignment="left" Width="Auto" Grid.RowSpan="2">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
</StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Titles}" Foreground="Black" Width="189" Height="34" TextWrapping="Wrap" Padding="0,0,0,0"></TextBlock>
<Image Source="{Binding Images}" Width="189" Height="195" Name="value" Stretch="Fill" VerticalAlignment="Top" ></Image>
<TextBlock Text="Text1" Margin="0,0,10,0" HorizontalAlignment="Stretch" Grid.Column="0" Grid.Row="1" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Grid>
XDocument xmlDoc = XDocument.Parse(dataInXmlFile);
var query = from l in xmlDoc.Descendants("Category")
select new Class
{
Titles = l.Attribute("title").Value,
Images = l.Attribute("image").Value,
Articles = l.Element("SubCategory").Elements("Subcategory")
.Select(article => new Subclass
{
name = article.Attribute("name").Value,
Subimage = article.Attribute("subimage").Value,
Product = article.Element("Product").Elements("product")
.Select(articles => new Product
{
Price = articles.Element("productprice").Value,
ProductName = articles.Attribute("name").Value,
ProductImage = articles.Element("productimage").Value,
Shortdescription = articles.Element("productshortdiscription").Value
}).ToList(),
})
.ToList(),
};
foreach (var result in query)
{
Console.WriteLine(result.Titles);
Console.WriteLine(result.Images);
}
List12.DataContext = query;
I got out put like given below
1.Door 2.window 3.table 4.chair
I need out put like given below image
1.Door 2.window
3.table 4.chair
make ur stackPanel Orientation Vertical instead of Horizontal
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" VerticalAlignment="Top">
</StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
Dont use grid, instead use LongListSelector using LayoutMode=Grid
Example:
<phone:LongListSelector ItemsSource="{Binding Categories}" LayoutMode="Grid" GridCellSize="200,200">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Border Background="#e67e22" Height="190" Width="190" Margin="6,0,0,0" Tap="Border_Tap" >
<TextBlock Text="{Binding Name}"></TextBlock>
</Border>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>

display a long text inside a textblock on two lines

I have a listbox which contains a textblock and an image. I want if the text is too long it goes to a second line. At the moment only have of the text is visible. Here is my XAML
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding imgurl}" MaxHeight="120" MaxWidth="120" Margin="0,10,0,0" />
<TextBlock Text="{Binding title}" Margin="50,0,12,0" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
Could anybody help me?
Screenshot
Ah ya, so I guess it is as simple as it looked. You just need to restrict the width of where your text is and invoke TextWrapping, which you have multiple options to accomplish that. Here's a couple possibilities...
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding imgurl}" MaxHeight="120" MaxWidth="120" Margin="0,10,0,0" />
<TextBlock Text="{Binding title}" Margin="50,0,12,0" TextWrapping="Wrap" MaxWidth="{Binding ActualWidth, ElementName=Self}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
Or you could have a panel do it which should get restricted by its parent...
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding imgurl}" MaxHeight="120" MaxWidth="120" />
<TextBlock Grid.Column="1" Text="{Binding title}" TextWrapping="Wrap" Margin="50,0,2,0" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
Or depending on how this ListBox is layed out as a child, it could possibly even be as easy as just adding TextWrapping="Wrap" to the TextBlock and then setting the MaxWidth on the ListBox itself. Either way, hope this helps... :)

WP7 - access to sample data from code

In expression blend I created a sample data source in visual editor. In case of using a listbox I simply drag the collection there and data is automatically shown.
Now, I am interested to retrieve data from datasource from code behind. Is this possible?
There are a couple ways to do this, I will give you the simplest. I have a ListPicker that is bascially the same as a ListBox: Here is my ListPicker markup: Also here is a link
<toolkit:ListPicker Name="lpDrag" Grid.Row="4" Grid.Column="1" Loaded="lptest_Loaded" SelectedIndex="0">
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding name}" />
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
<toolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" ></ColumnDefinition>
<ColumnDefinition ></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding name}" FontSize="26" Grid.Column="0" Grid.Row="0"/>
<TextBlock Text="{Binding desc}" TextWrapping="Wrap" FontSize="26" Grid.Column="1" Grid.Row="0" />
</Grid>
</DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>
Here is the code behind:
lpDrag.ItemsSource = //Whatever your datasource is

Get content of control inside listbox item when it was clicked

I have a ItemTemplate like this
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="0">
<Button.Template>
<ControlTemplate>
<Border BorderBrush="AntiqueWhite" BorderThickness="1">
<StackPanel Orientation="Horizontal" Background="Gray" Width="465">
<Image Margin="2,0,10,0" Source="{Binding StateImage}" Stretch="None"/>
<TextBlock Name="txt" Text="{Binding DateLabel}"/>
</StackPanel>
</Border>
</ControlTemplate>
</Button.Template>
<Custom:Interaction.Triggers>
<Custom:EventTrigger EventName="Click">
<mx:EventToCommand Command="{Binding VisibilityListboxCommand}"
CommandParameter="{Binding EementName=txt, Path=Text}"
/>
</Custom:EventTrigger>
</Custom:Interaction.Triggers>
</Button>
<ListBox Grid.Column="1" ItemsSource="{Binding WhatsonList, Mode=OneWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Gray" BorderThickness="0,0,0,1" Padding="0,0,0,10">
<Grid Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="360"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<Button>
.....
</Button>
<CheckBox Template="{StaticResource CheckboxImageTemplate}" Margin="0,5,0,0"/>
</StackPanel>
<ListBox Grid.Column="1">
.....
</ListBox>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
When I click on button inside listboxitem datatemplate I want to get content of textblock txt to find out what listbox item was clicked to trace back index in the List(model) that listbox bind from.
But from commandparameter I cannot get anything because there are many textblock named txt I think.
Please help me !
A better way to solve this is by binding the CommandParameter to 'thing' in the DataContext of the item like this:
<Custom:Interaction.Triggers>
<Custom:EventTrigger EventName="Click">
<mx:EventToCommand Command="{Binding VisibilityListboxCommand}"
CommandParameter="{Binding}" />
</Custom:EventTrigger>
</Custom:Interaction.Triggers>
This way the binding does not rely on a particular control being present and having a specific name.

Resources