Windows 8 - XAML - Conditional background for row in ListView - windows

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>

Related

How can we set a default color `#c4bfc7` for row records displaying in the Xamarin forms page

Where do we set a default color #c4bfc7 for row records displaying in the page, below is the xaml. Now while tapping, it is showing some color, which is fine. But I want to display some color for rows by default
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding image}" WidthRequest="50" HeightRequest="50" Grid.Column="0" VerticalOptions="Center"/>
<StackLayout Grid.Column="1">
<Label Text="{Binding FullName}" TextColor="White" HorizontalTextAlignment="Start"/>
</StackLayout>
<StackLayout Grid.Column="2">
<Label Text="{Binding SoccerStatus}" HorizontalTextAlignment="Center" TextColor="White"/>
</StackLayout>
<StackLayout Grid.Column="3">
<Label Text="{Binding CurrentDate}" HorizontalTextAlignment="Center" TextColor="White"/>
</StackLayout>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
UPDATE
Your grid inside the ViewCell would look something like below:
<Grid BackgroundColor="#c4bfc7">
First of all, you might wanna add a property for hex code in your model that is bound to your ListView
public class ListModel
{
public string HexCode{get; set;}
}
Now when you are filling this model based on your conditions push in the correct hex code that you want as that items background colour. Once you are done with that your listview would look something like below:
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid BackgroundColor={Binding HexCode}>
Then add a convertor that converts hex to colour:
public class HexToColorConvertor : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string colorHex = (string)value;
if (string.IsNullOrEmpty(colorHex) && string.IsNullOrWhiteSpace(colorHex))
return Color.White;
return Color.FromHex(colorHex); //Note that if the hex code is not valid this might crash
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
// Not implemented as we do not convert back
throw new NotSupportedException();
}
}
Now add this convertor to your resources like below:
<common:HexToColorConvertor x:Key="HexToColor" />
Where common is the namespace of that convertor and then use it like below:
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid BackgroundColor={Binding HexCode, Converter={StaticResource HexToColor}}>
You should set #c4bfc7 background colour to outmost view which is is grid inside view cell here.
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid BackgroundColor="#c4bfc7">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding image}" WidthRequest="50" HeightRequest="50" Grid.Column="0" VerticalOptions="Center"/>
<StackLayout Grid.Column="1">
<Label Text="{Binding FullName}" TextColor="White" HorizontalTextAlignment="Start"/>
</StackLayout>
<StackLayout Grid.Column="2">
<Label Text="{Binding SoccerStatus}" HorizontalTextAlignment="Center" TextColor="White"/>
</StackLayout>
<StackLayout Grid.Column="3">
<Label Text="{Binding CurrentDate}" HorizontalTextAlignment="Center" TextColor="White"/>
</StackLayout>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
Furthermore If you want to change the list view selected item color.
Here is an answer which worked for me. It includes adding few keys to android's style.xml
https://stackoverflow.com/a/38457882/4707196

Xamarin form: BindingProperty not setting the property

I am having trouble on my custom control with binding property. It used to be worked when pcl project. After pulling the code out into .net standard 2.0 with latest xamarin form package, it's not working.
This is the setup i have
public static readonly BindableProperty ChildProperty = BindableProperty.Create(nameof(Child), typeof(ChildModel), typeof(ChildModel), null, BindingMode.OneWay, propertyChanging: (BindableObject bindable, object oldValue, object newValue) => {
var a = newValue;
});
and the property is
public ChildModel Child
{
get
{
return (ChildModel)GetValue(ChildProperty);
}
set
{
SetValue(ChildProperty, value);
}
}
I can see newValue does have the childModel data passing in the callback. The GetValue of the second set of code always return null.
<ListView
Style="{StaticResource listStyle}"
AutomationId="listChildren"
CachingStrategy="RecycleElement"
x:Name="childListView"
ItemSelected="OnItemSelected"
ItemTapped="OnItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Frame HasShadow="false" Padding="{StaticResource cellPadding}">
<local:ExtendedFrame Style="{StaticResource cardStyle}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{StaticResource profileGridSize}"></ColumnDefinition>
<ColumnDefinition>*</ColumnDefinition>
</Grid.ColumnDefinitions>
<controls:CircleImage
Grid.Row="0"
Grid.Column="0"
Style="{StaticResource profileImageStyle}"
Source="{Binding Source}"
VerticalOptions="Center"
HorizontalOptions="Center">
</controls:CircleImage>
<StackLayout Orientation="Vertical"
Grid.Row="0"
Grid.Column="1"
VerticalOptions="Center"
HorizontalOptions="Start">
<Label AutomationId="aChildName" Style="{StaticResource MediumBoldFont}" x:Name="childName" Text="{Binding DisplayName}" HorizontalOptions="StartAndExpand" />
<local:ChildInfoIconsView
Child="{Binding .}"
VerticalOptions="Fill">
</local:ChildInfoIconsView>
</StackLayout>
</Grid>
</local:ExtendedFrame>
</Frame>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

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

Issue with binding itemsource using MVVM in WP7

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());

Binding list Collection from a list collection in Window Phone 7

How to Binding list Collection from a list collection in Window Phone 7 while i am able to bind from a single list collection
First of all have item template in your Xaml.
Add Binding to it.
Define that binding property in your code.
Assign values to the defined property.
I am having a item template in my Xaml like this :
<Grid.RowDefinitions>
<RowDefinition Height="367*" />
</Grid.RowDefinitions>
<ListBox HorizontalAlignment="Stretch" Name="lstbNewOrders" Grid.Row="1" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid x:Name="itemTemplate" Background="Transparent" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<TextBlock FontSize="30" Name="txtEbeln" Text="{Binding ebeln}" Grid.Row="0" Grid.Column="0" FontWeight="Bold" />
<TextBlock FontSize="25" Name="txtCName" Text="{Binding cname}" Grid.Row="1" Grid.Column="0" />
<TextBlock FontSize="25" Name="txtDate" Text="{Binding date}" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" TextAlignment="Right"/>
<StackPanel Height="30" Name="stkPanel01" HorizontalAlignment="Right" Grid.Row="0" Grid.Column="1">
<TextBlock FontSize="25" Name="txtNetw" Text="{Binding netw}" HorizontalAlignment="Right" TextAlignment="Right"/>
</StackPanel>
<TextBlock FontSize="25" Name="txtVName" Text="{Binding vname}" Grid.Row="2" Grid.Column="0" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
In my code file i will define the binding like this:
public class itemListForListBox
{
public string ebeln { get; set; }
public string cname { get; set; }
public string vname { get; set; }
public string netw { get; set; }
public string date { get; set; }
}
And provide values like this:
void fillList()
{
List<itemListForListBox> itemListbox = new List<itemListForListBox>();
itemListForListBox listItem;
for (int i = 0; i < 5;i++ )
{
listItem = new itemListForListBox();
listItem.ebeln = "Name "+i;
listItem.date = "Date "+i;
listItem.vname = "VName "+i;
listItem.netw = "Amount "+ i;
listItem.cname = "CName "+i;
itemListbox.Add(listItem);
}
lstbNewOrders.ItemsSource = itemListbox;
}
Hope this might help you.
Thanks.
You can use the code below,
<ListBox Name="RouteListBox" ItemContainerStyle="{StaticResource RouteListBoxItemStyle}" SelectedItem="{Binding Model.SelectedRoute,Mode=TwoWay}" ItemsSource="{Binding RouteListCollection}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<command:EventToCommand Command="{Binding RouteItemSelectedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding RouteName}" Style="{StaticResource RoutesStyle}" Grid.Column="1" />
<Border Style="{StaticResource RouteCountBorder}" Visibility="Collapsed" Grid.Column="2">
<TextBlock Style="{StaticResource RoutesCount}" Visibility="Collapsed" Text="{Binding ShopCount,Mode=TwoWay}"></TextBlock>
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate></ListBox>
I take it you mean you have a collection of collections? In this case, you can nest your ItemsControls (or ListBox):
<ItemsControl ItemsSource={Binding Path=???}>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- here is your nested itemscontrol -->
<ItemsControl ItemsSource={Binding Path=???}>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- your content goes here -->
</DataTemplate>
<ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Let say we have a ListBox lstbx and a collection lets say
List <String> listdata = new List<String>();
we can add items to the collection by Add()
Ex-
listdata.Add("Nazi 1");
or
forloop(expression)
{
listdata.Add("vale")
}
then we can assign assign the collection directly to the listbox' item Source
ex.
lstbx.ItemSource=listdata;
//make sure if u are storing more than one variable in a single item of the collection ,you should create custom data template for the ListBox Item Template. !

Resources