I am making an application with Xamarin Forms. I want the app to display a list view similar to youtube. There is a thumbnail on the left and on the right there is a Video Title with details underneath. Currently, I am only able to place the details on a single line.
How would I seperate the details into multiple lines within the Image Cell?
Currently:
Homepage.xaml:
<StackLayout Orientation="Vertical">
<SearchBar x:Name="MainSearchBar" HorizontalOptions="Center" />
<ListView x:Name="VideoList" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell Text = "{Binding Title}" Detail="{Binding Detail}" ImageSource="{Binding ImageURL}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
Videos.cs:
class Videos
{
public string Title { get; set; }
public string Author { get; set; }
public int Views { get; set; }
public DateTime Upload_DateTime { get; set; }
public string ImageURL { get; set; }
public string Detail
{
get
{
return string.Format("{0} - {1} Views Uploaded: {2} ", Author, Views, Upload_DateTime); //format for details on imagecell
}
}
}
NOTE: I have tried the following formats on Videos.cs:
return string.Format("{0} - {1} Views \nUploaded: {2} ", Author, Views, Upload_DateTime);
return string.Format("{0} - {1} Views
Uploaded: {2} ", Author, Views, Upload_DateTime);
Thanks #Jason!
Now I have a grid layout inside of a View Cell. It seems to be exactly what I needed! Next, I will need to correct the formatting to make it look prettier, but for the most part, this question is answered!
Homepage.xaml:
<StackLayout Orientation="Vertical">
<SearchBar x:Name="MainSearchBar" HorizontalOptions="Center" />
<ListView x:Name="VideoList" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image Source="{Binding ImageURL}" Grid.Row="0" Grid.Column="0" Grid.RowSpan="3"/>
<Label Text="{Binding Title}" Grid.Row="0" Grid.Column="1"/>
<Label Text="{Binding Author_Views}" Grid.Row="1" Grid.Column="1"/>
<Label Text="{Binding Uploaded}" Grid.Row="2" Grid.Column="1"/>
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
Related
I have created the following ListView to display data
<dataControls:RadListView x:Name="ItemsListView"
ItemsSource="{Binding StudyResults,Mode=TwoWay}"
MinimumHeightRequest="70"
HeightRequest="{Binding Height}"
SelectedItem="{Binding SelectedItem,Mode=TwoWay}">
<dataControls:RadListView.ItemTemplate>
<DataTemplate>
<listView:ListViewTemplateCell>
<listView:ListViewTemplateCell.View>
<Grid Padding="2,2,2,5" HorizontalOptions="FillAndExpand">
<StackLayout Padding="5,1,1,5" Grid.Column="0">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<maxline:XfMaxLinesLabel MaxLines="2" Text="{Binding BriefTitle, Mode=TwoWay}" Style="{StaticResource ListViewLabelStyle}" TextColor="Black"/>
</Grid>
<StackLayout Padding="0,0,0,0" HorizontalOptions="Fill">
<BoxView Margin="0"
BackgroundColor="Gray"
HeightRequest=".25" />
<Label Text="{Binding ClosestFacility.Name, Mode=TwoWay}" Style="{StaticResource ListViewLabelStyle}"/>
<BoxView Margin="0"
BackgroundColor="Gray"
HeightRequest=".25" />
</StackLayout>
</StackLayout>
</Grid>
</listView:ListViewTemplateCell.View>
</listView:ListViewTemplateCell>
</DataTemplate>
</dataControls:RadListView.ItemTemplate>
</dataControls:RadListView>
I want to reuse this exact same ListView + markup in a other screens/view, just with a different ItemsSource it will be bound to same model. I need to use different item source in different screens.
Is there a better way to create some type of resource so I can reuse this?
As lvan's opinion, you can set DataTemplate in ContentPage.Resource or ResourceDictionary, Some code like this:
<ContentPage.Resources>
<DataTemplate x:Key="Radtemplate">
<listView:ListViewTemplateCell>
<listView:ListViewTemplateCell.View>
<Grid Padding="2,2,2,5" HorizontalOptions="FillAndExpand">
<StackLayout Padding="5,1,1,5" Grid.Column="0">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<maxline:XfMaxLinesLabel MaxLines="2" Text="{Binding BriefTitle, Mode=TwoWay}" Style="{StaticResource ListViewLabelStyle}" TextColor="Black"/>
</Grid>
<StackLayout Padding="0,0,0,0" HorizontalOptions="Fill">
<BoxView Margin="0"
BackgroundColor="Gray"
HeightRequest=".25" />
<Label Text="{Binding ClosestFacility.Name, Mode=TwoWay}" Style="{StaticResource ListViewLabelStyle}"/>
<BoxView Margin="0"
BackgroundColor="Gray"
HeightRequest=".25" />
</StackLayout>
</StackLayout>
</Grid>
</listView:ListViewTemplateCell.View>
</listView:ListViewTemplateCell>
</DataTemplate>
</ContentPage.Resources>
<StackLayout>
<!-- Place new controls here -->
<dataControls:RadListView x:Name="ItemsListView" ItemTemplate="{StaticResource Radtemplate}"
ItemsSource="{Binding StudyResults,Mode=TwoWay}"
MinimumHeightRequest="70"
HeightRequest="{Binding Height}"
SelectedItem="{Binding SelectedItem,Mode=TwoWay}">
</dataControls:RadListView>
</StackLayout>
About DateTemplate detailed info, you can take a look the following article:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/templates/data-templates/creating
Update:
Because RadListView is the third party control, I can not install it, so I use ListView as an example, it is the same, you can take a look how to use TapGestureRecognizer.
Please give the Page an x:name=listviewpage firstly, then
<ContentPage
x:Class="demo3.listviewsample.Page2"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="listviewpage"
mc:Ignorable="d">
<ContentPage.Resources>
<DataTemplate x:Key="datatemplate1">
<ViewCell>
<StackLayout Margin="5" VerticalOptions="FillAndExpand">
<BoxView BackgroundColor="AliceBlue" HeightRequest="30" />
<Label Text="{Binding username}">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding BindingContext.command, Source={x:Reference listviewpage}}" CommandParameter="{Binding Email}" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<ListView
HasUnevenRows="True"
ItemTemplate="{StaticResource datatemplate1}"
ItemsSource="{Binding models}" />
</StackLayout>
</ContentPage.Content>
Or you can give ViewCell an x:Name viewcell1 firstly, then:
<ContentPage.Resources>
<DataTemplate x:Key="datatemplate1">
<ViewCell x:Name="viewcell">
<StackLayout Margin="5" VerticalOptions="FillAndExpand">
<BoxView BackgroundColor="AliceBlue" HeightRequest="30" />
<Label Text="{Binding username}">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Parent.BindingContext.command, Source={x:Reference viewcell}}" CommandParameter="{Binding Email}" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ContentPage.Resources>
public partial class Page2 : ContentPage
{
public ObservableCollection<model3> models { get; set; }
public RelayCommand1 command { get; set; }
public Page2()
{
InitializeComponent();
models = new ObservableCollection<model3>()
{
new model3(){username="cherry",Email="cherry#outlook.com"},
new model3(){username="barry",Email="barry#outlook.com"}
};
command = new RelayCommand1(obj => method1((string)obj));
this.BindingContext = this;
}
private void method1(string str)
{
Console.WriteLine("the email is {0}",str);
}
}
public class model3
{
public string username { get; set; }
public string Email { get; set; }
}
Here is the Command that inherit ICommand:
public class RelayCommand1 : ICommand
{
private readonly Predicate<object> _canExecute;
private readonly Action<object> _execute;
public RelayCommand1(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand1(Action<object> execute, Predicate<object> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_execute(parameter);
}
}
When I tap label, it works fine.
You can set DataTemplate as resource, that would work.
Hello I’m having an issue with binding a list of string to my Carousel View
First I have a list of an object I get from my server
public class PostObject
{
public string PostOwner { get; set; }
public string Id { get; set; }
public string Post { get; set; }
public string ProfileImage { get; set; }
public List<string> PostImages { get; set; }
}
List<PostObject> posts = new List<PostObject>();
This works as I expected.
Next I have a card view I created and within the card view I want to have a Carousel View.
So I have setup my Xaml like this (omitting the parts that works for clarity)
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin"
NavigationPage.HasNavigationBar="True"
NavigationPage.HasBackButton="False"
NavigationPage.BackButtonTitle="Back"
Title="amici"
x:Class="amici.Posts">
<NavigationPage.TitleView>
<StackLayout Orientation="Horizontal" VerticalOptions="Center" Spacing="10" >
<Label x:Name="GroupTitle" TextColor="White" FontSize="Medium"/>
</StackLayout>
</NavigationPage.TitleView>
<ContentPage.ToolbarItems>
<ToolbarItem Name="iconexample" Icon="settings.png" Priority="0" Order="Primary" />
</ContentPage.ToolbarItems>
<ContentPage.Content>
<StackLayout>
<ListView x:Name="ItemsListView"
VerticalOptions="FillAndExpand"
HasUnevenRows="true"
IsPullToRefreshEnabled="true"
IsRefreshing="{Binding IsBusy, Mode=OneWay}"
CachingStrategy="RecycleElement">
<!--ItemSelected="OnItemSelected"-->
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell >
<StackLayout Padding="10">
<Frame x:Name="myframe" HasShadow="True" >
<Grid HorizontalOptions="FillAndExpand" RowSpacing="0" ColumnSpacing="0" >
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="20" />
<RowDefinition Height="20" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Text="{Binding PostOwner}" LineBreakMode="WordWrap" Font="Bold,16" />
<controls:CircleImage Grid.Row="0" Margin="10" BorderColor="white" BorderThickness="1" VerticalOptions="Start" HorizontalOptions="Start" Source="{Binding ProfileImage}" Aspect="AspectFit">
<controls:CircleImage.WidthRequest>
<OnPlatform x:TypeArguments="x:Double">
<On Platform="Android, iOS">65</On>
</OnPlatform>
</controls:CircleImage.WidthRequest>
<controls:CircleImage.HeightRequest>
<OnPlatform x:TypeArguments="x:Double">
<On Platform="Android, iOS">65</On>
</OnPlatform>
</controls:CircleImage.HeightRequest>
</controls:CircleImage>
<Label Grid.Row="1" Text="{Binding Post}" LineBreakMode="WordWrap" Font="Bold,16" />
<CarouselView x:Name="PostImages" Grid.Row="2" ItemsSource="{Binding PostImages}">
<CarouselView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding .}" Aspect="AspectFill" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<!--<Image Grid.Row="2" Source="{Binding ImageURL}" Aspect="AspectFill" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />-->
<BoxView Grid.Row="3" BackgroundColor="black" HeightRequest="1" HorizontalOptions="FillAndExpand"/>
<StackLayout Grid.Row="4" Orientation="Horizontal" >
<Label Text="Likes: " LineBreakMode="NoWrap" Font="Bold,14" />
<Label Text="0" LineBreakMode="NoWrap" FontSize="14" />
</StackLayout>
<StackLayout Grid.Row="5" Orientation="Horizontal" >
<Label Text="Comments: " LineBreakMode="NoWrap" Font="Bold,14" HorizontalOptions="End" />
<Label Text="0" HorizontalOptions="End" LineBreakMode="NoWrap" FontSize="14" />
</StackLayout>
<!--<Label Grid.Row="2" Text="{Binding OwnerFullName}" LineBreakMode="NoWrap" FontSize="16" />-->
</Grid>
</Frame>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
In my code behind I have this
public Posts (GroupInfo ginfo)
{
InitializeComponent ();
GroupTitle.Text = ginfo.Title;
CurrentGroupInfo = ginfo;
GetDataPosts();
ItemsListView.RefreshCommand = new Command(() => {
GetDataPosts();
ItemsListView.IsRefreshing = false;
});
}
public void GetDataPosts()
{
try
{
string apikey = Application.Current.Properties["api"].ToString();
ItemsListView.ItemsSource = null;
posts.Clear();
if (RestController.GetMyPostData(ref posts, CurrentGroupInfo.Id.ToString(), apikey))
{
ItemsListView.ItemsSource = posts;
}
}
catch(Exception e)
{
Debug.WriteLine(e.Message);
}
}
now up to this point everything works and no errors but when the app goes to render the page I get a error
System.TypeInitializationException: The type initializer for 'Xamarin.Forms.ItemsView' threw an exception.
which I trace back to the Carousel View. When I comment out the Carousel View the it works. so I'm thinking I can't bind OR use the Carousel View in the way I thought?
The CarouselView used to be a plugin that has now become part of Xamarin.Forms effective with version 4. You can use an earlier XF version but you will need to get this plugin, add assembly references to your XAML and put initialization code in your platform specific projects.
Alternatively, you could upgrade to Xamarin.Forms 4
Even though you can see the Carousel View on Xamarin.Forms 3.6.0.344457, it only defines an interface there. There're no implementations and properties in the Carousel View Class.
You can only utilize it under Xamarin.Forms 4.0. As it is still a preview version now, there're some limitations. See my post here: https://stackoverflow.com/a/56235795/8354952 for more information.
i have a nested List Object and i want to bind them to the list all my data is proper also i have implemented INotifyChanged Event but the data on the UI Is not displays
here is my Xaml UI
<ListView x:Name ="lstView" Margin="0,5,0,5" VerticalScrollBarVisibility="Always" HasUnevenRows="True" VerticalOptions="FillAndExpand" ItemsSource="{Binding Grouped}" IsGroupingEnabled="true" SelectionMode="None" SeparatorVisibility="None" GroupDisplayBinding="{Binding LongName}" GroupShortNameBinding="{Binding ShortName}">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<Grid Margin="5,20,0,0" RowSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="95*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="radiochecked.png" VerticalOptions="End" />
<Frame Grid.Column="1" HasShadow="False" HorizontalOptions="Start" Padding="6,2,6,2" BackgroundColor="#608EF6">
<Label Text="{Binding LongName}" TextColor="White" VerticalTextAlignment="Center" ></Label>
</Frame>
</Grid>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="5,0,10,0" HorizontalOptions="FillAndExpand" RowSpacing="0" VerticalOptions="FillAndExpand" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="95*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="70"/>
</Grid.RowDefinitions>
<BoxView
Grid.Column="0" Grid.Row="0"
BackgroundColor="#566781"
HorizontalOptions="Center"
VerticalOptions="Fill"
WidthRequest="2" />
<Image Grid.Column="0" Grid.Row="1" Source="radiochecked.png" />
<BoxView
Grid.Column="0" Grid.Row="2"
BackgroundColor="#566781"
HorizontalOptions="Center"
VerticalOptions="Fill"
WidthRequest="2" />
<Frame Grid.Column="1" Grid.Row="0" HasShadow="False" Grid.RowSpan="3" Padding="0,0,2,0" Margin="0,10,0,5" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal" VerticalOptions="FillAndExpand">
<BoxView BackgroundColor="{Binding EncounterFrameColor}" WidthRequest="3"></BoxView>
<Grid Margin="0,8,0,0" HorizontalOptions="FillAndExpand" VerticalOptions="Start">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackLayout Spacing="0" Grid.Column="0">
<Label Text="{Binding EncounterMonth}" Margin="3,1,0,0" FontSize="10" TextColor="Black" VerticalOptions="Start" HorizontalOptions="Start"></Label>
<Label Text="{Binding MDate}" Margin="3,2,0,0" FontSize="15" TextColor="Black" FontAttributes="Bold" HorizontalTextAlignment="Center" VerticalOptions="Start" HorizontalOptions="Start"></Label>
</StackLayout>
<StackLayout Grid.Column="2" VerticalOptions="Start" Grid.Row="0" HorizontalOptions="FillAndExpand">
<Grid RowSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="15"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Source="{Binding EncounterImage}" Margin="0,2,0,0" VerticalOptions="Start" Grid.Row="0" Grid.Column="0"/>
<Label Text="{Binding Encounter}" TextColor="Black" FontSize="12" Grid.Row="0" VerticalOptions="Start" Grid.Column="1" ></Label>
<StackLayout Margin="0,0,0,5" Spacing="0" BindableLayout.ItemsSource="{Binding UserVitals}" Grid.Row="1" Grid.Column="1" >
<BindableLayout.ItemTemplate>
<DataTemplate>
<Grid RowSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding Description}" Grid.Column="0" FontSize="10" TextColor="Black" />
<Label Text="{Binding Values}" HorizontalOptions="Start" Grid.Column="2" FontSize="10" TextColor="Black"/>
</Grid>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</Grid>
</StackLayout>
</Grid>
</StackLayout>
</Frame>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
i am trying to create Grouping Listview Which is grouping with the Year
here is my Model
public class EncounterFrameModel
{
public string EncounterMonth { get; set; }
public string MDate { get; set; }
public string Comment { get; set; }
// public bool IsReallyAVeggie { get; set; }
public string EncounterFrameColor { get; set; }
public string Image { get; set; }
public string Encounter { get; set; }
// public List<TotalItem> Totals { get;set; }
public string EncounterImage { get; set; }
public ObservableCollection<UserHealthDetails> UserVitals { get; set; }
public EncounterFrameModel()
{
}
}
public class UserHealthDetails
{
public string Description { get; set; }
public string Values { get; set; }
}
public class EncounteredYear
{
public EncounteredYear()
{
encounterFrameModels = new ObservableCollection<EncounterFrameModel>();
}
public string LongName { get; set; }
public string ShortName { get; set; }
public ObservableCollection<EncounterFrameModel> encounterFrameModels { get; set; }
}
can any one help me in binding this data
you could try this:
change your EncounteredYear model like this:
class EncounteredYear:ObservableCollection<EncounterFrameModel>
{
public string LongName { get; set; }
public string ShortName { get; set; }
}
in your page.xaml.cs set your data(Generate data according to your own situation):
ObservableCollection<EncounteredYear> grouped = new ObservableCollection<EncounteredYear>();
var gounp1 = new EncounteredYear() {...};
var gounp2 = new EncounteredYear() {...};
var gounp3 = new EncounteredYear() {...};
gounp1.Add(new EncounterFrameModel() {...});
gounp1.Add(new EncounterFrameModel() {...});
gounp1.Add(new EncounterFrameModel() {...});
gounp1.Add(new EncounterFrameModel() {...});
gounp2.Add(new EncounterFrameModel() {...});
gounp2.Add(new EncounterFrameModel() {...});
gounp2.Add(new EncounterFrameModel() {...});
gounp2.Add(new EncounterFrameModel() {...});
gounp3.Add(new EncounterFrameModel() {...});
gounp3.Add(new EncounterFrameModel() {...});
gounp3.Add(new EncounterFrameModel() {...});
gounp3.Add(new EncounterFrameModel() {...});
grouped.Add(gounp1);
grouped.Add(gounp2);
grouped.Add(gounp3);
lstView.ItemsSource = grouped;// bind the list of the grouplist
then you page's xaml as your before but delete ItemsSource="{Binding Grouped}" and must add <ViewCell> inside <DataTemplate>:
<ListView x:Name ="lstView" Margin="0,5,0,5" VerticalScrollBarVisibility="Always" HasUnevenRows="True" VerticalOptions="FillAndExpand" IsGroupingEnabled="true" SelectionMode="None" SeparatorVisibility="None" GroupDisplayBinding="{Binding LongName}" GroupShortNameBinding="{Binding ShortName}">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
...
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
...
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I have a listview in which i have data, in listview i have
1 - taskname
2- date
3 - completed percentage
4 - Assigned task by
I want to put condition in list and based on condition want to change color of list row, for example if completed percentage =0, color of that row should be white if percentage is greater then 0 color should be red etc etc.
check image down below:
in listview i have 0%, 7% and 100 %, so i want if its 0 row color should be white, if its more then 0 row color should b red and if its = 100 row color should be green here is my xaml code
<ListView HeightRequest="20" HasUnevenRows="True" SeparatorColor="Red" ItemsSource="{Binding GetAssignedTask}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell >
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image Grid.Row="0" Grid.Column="0" Source="rsz_pnglogocom.png" />
<Label Grid.Row="0" Grid.Column="1" Text="{Binding strTaskName}" TextColor="Black" FontSize="Medium" />
<Label Grid.Row="1" Grid.Column="1" Text="{Binding intCurrCompletePercentage , StringFormat='{0}% Completed '}" Margin="0,0,10,0" TextColor="Black" />
<Label Grid.Row="1" Grid.Column="2" Margin="0,0,20,0" Text="{Binding dtStart,StringFormat='{0:MMMM dd, yyyy}'}" TextColor="Red" HorizontalOptions="Center"/>
<Label Grid.Row="1" Grid.Column="3" Text="{Binding strAssignedByEmpName}" TextColor="Black" HorizontalOptions="End"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Two ways to do this.
1. Using Converters:
Create a Value converter:
public class BackgroundColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
if(value!=null)
{
if((int)value ==0)
return Color.White;
else if((int)value > 0)
return Color.Red;
else
return Color.Green;
}
}
catch (Exception ex)
{
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
xaml part:
xmlns:converter="RefrenceToConverterNameSpace"
<ContentPage.Resources>
<ResourceDictionary>
<converter:BackgroundColorConverter x:Key="BackgroundColorConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<Grid BackgroundColor="{Binding intCurrCompletePercentage,Converter={StaticResource BackgroundColorConverter}}" />
Method 2:
In your object which containts intCurrCompletePercentage
You can also have another property Color property PercentColor
public Color PercentColor
{
get
{
if(intCurrCompletePercentage ==0)
return Color.White;
else if(intCurrCompletePercentage > 0)
return Color.Green;
else
return Color.Red;
}
}
<Grid BackgroundColor="{Binding PercentColor}" />
Whenever your intCurrCompletePercentage changes dont forget to call the propertychanged event for PercentColor.
You could also have a look at DataTemplateSelector for this case.
A look in the documentation https://learn.microsoft.com/de-de/xamarin/xamarin-forms/app-fundamentals/templates/data-templates/selector
Code from documentation
public class PersonDataTemplateSelector : DataTemplateSelector
{
public DataTemplate ValidTemplate { get; set; }
public DataTemplate InvalidTemplate { get; set; }
protected override DataTemplate OnSelectTemplate (object item, BindableObject container)
{
return ((Person)item).DateOfBirth.Year >= 1980 ? ValidTemplate : InvalidTemplate;
}
}
XAML
<ContentPage.Resources>
<ResourceDictionary>
<DataTemplate x:Key="validPersonTemplate">
<ViewCell>
...
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="invalidPersonTemplate">
<ViewCell>
...
</ViewCell>
</DataTemplate>
<local:PersonDataTemplateSelector x:Key="personDataTemplateSelector"
ValidTemplate="{StaticResource validPersonTemplate}"
InvalidTemplate="{StaticResource invalidPersonTemplate}" />
</ResourceDictionary>
</ContentPage.Resources>
<ListView x:Name="listView" ItemTemplate="{StaticResource personDataTemplateSelector}" />
You would have to make 3 templates (ZeroTemplate, AboveZeroTemplate, HundredTemplate) and let your DataTemplateSelector decide which template it should take.
I posted just the documentation code, because I think you always should do something on yourself to also learn something, and not just copy paste.. :)
I have a Xamarin Forms application using Android and UWP. Everything works fine under Android but under UWP I have a problem when I want to modify some values displayed on the screen.
Here is my (simplified) ViewModel (using Fody.PropertyChanged) :
public class SalesViewModel : BaseAppViewModel
{
public ObservableCollection<SaleModel> Sales { get; set; }
= new ObservableCollection<SaleModel>();
[DoNotNotify]
public ICommand AddQuantityCommand => new Command<SaleModel>(item =>
{
item.Quantity += 1;
});
}
The BaseAppViewModel implement the INotifyPropertyChanged interface for Fody.PropertyChanged
The (simplified) SaleModel class:
public class SaleModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public double Quantity { get; set; }
}
And the (part of the) XAML which display the list of SaleModel's
<ListView x:Name="ListView" ItemsSource="{Binding Sales, Mode=TwoWay}" SelectedItem="{Binding SelectedSale, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="arrow.png">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.AddQuantityCommand, Source={x:Reference Name=SalesPage}}" CommandParameter="{Binding .}" />
</Image.GestureRecognizers>
</Image>
<Label Grid.Column="1" Text="{Binding Quantity, Mode=OneWay}"
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
When clicking on the Image, the quantity is incremented but the value disappear from the screen under UWP.
I have tested your code and reproduced your issue. And I written the following ViewCell replace yours. Please try to modify your ViewCell.
<ViewCell>
<StackLayout BackgroundColor="#eee"
Orientation="Vertical">
<StackLayout Orientation="Horizontal">
<Image Source="time.jpg" HeightRequest="50" WidthRequest="50" >
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding AddQuantityCommand} " CommandParameter="{Binding .}"/>
</Image.GestureRecognizers>
</Image>
<Label Text="{Binding Quantity}"
TextColor="#f35e20" />
<Label Text="{Binding Quantity}"
HorizontalOptions="EndAndExpand"
TextColor="#503026" />
</StackLayout>
</StackLayout>
</ViewCell>
I have upload code sample to github. Please refer to.