ItemTemplate for list of items in Xamarin - c#

I have a ListView with an ItemTemplate. For each item in my ItemSource, I would like to iterate over a property in the item and create a section in my ViewCell.
So every item is a Download:
public class Download
{
public string Title { get; set; }
public IEnumerable<SectionDownload> SectionDownloads { get; set; }
}
SectionDownload looks like this:
public class SectionDownload
{
public long TotalBytes { get; set; }
public long DownloadedBytes { get; set; }
public int PercentDownloaded { get => (int)((DownloadedBytes / TotalBytes) * 100); }
}
And my ListView, where Downloads is an ObservableCollection<Download> in my ViewModel:
<ListView x:Name="DownloadsListView" SelectionMode="None" ItemsSource="{Binding Downloads}">
<ListView.ItemTemplate>
<DataTemplate>
<StackLayout Padding="10">
<Label Text="{Binding Title}"
d:Text="{Binding .}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemTextStyle}"
FontSize="16" />
<!-- Here I would like each SectionDownload to display the percentage downloaded -->
</StackLayout>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

You can display section like this.
<ListView x:Name="DownloadsListView" SelectionMode="None" ItemsSource="{Binding Downloads}">
<ListView.ItemTemplate>
<DataTemplate>
<StackLayout Padding="10">
<Label Text="{Binding Title}"
d:Text="{Binding .}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemTextStyle}"
FontSize="16" />
<StackLayout BindableLayout.ItemsSource="{Binding SectionDownloads}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<ProgressBar Progress="{Binding PercentDownloaded}" />
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</StackLayout>
</DataTemplate>
</ListView.ItemTemplate>
The value of PercentDownloaded should be double in range of 0 to 1 and also you have to implement the INotifyPropertyChange to your SectionDownload class for updating the progress in realtime.

The error is caused that you did not wrap Cell inside DataTemplate.
Modify it as
<ListView x:Name="DownloadsListView" SelectionMode="None" ItemsSource="{Binding Downloads}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell> //add this line
<StackLayout Padding="10">
<Label Text="{Binding Title}"
d:Text="{Binding .}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemTextStyle}"
FontSize="16" />
<StackLayout BindableLayout.ItemsSource="{Binding SectionDownloads}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<ProgressBar Progress="{Binding PercentDownloaded}" />
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>

Related

Xamarin Forms ListView Inside CollectionView

I have a collection view whose source is an IObservable(Object1) inside of each Object1 is a List(Object2).
I would like to show each Object2 that is related to its Object1.
I have tried to place a ListView inside of a collectionView
I am getting the error System.InvalidOperationException LoadTemplate should not be null
<CollectionView Grid.Row="2" ItemsSource="{Binding Object1Collection}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.65*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label TextColor="Black" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Text="{Binding Response}"></Label>
<Label TextColor="Black" Grid.Row="1" Grid.Column="0" Text="Restriction: "></Label>
<ListView Grid.Row="1" Grid.Column="1" ItemsSource="{Binding Object2List }">
<ListView.ItemTemplate>
<DataTemplate>
<!--
<StackLayout Orientation="Horizontal">
<Label TextColor="Black" Text="{Binding Statistic}"></Label>
<Label TextColor="Black" Text=" : "></Label>
<Label TextColor="Black" Text="{Binding Amount}"></Label>
</StackLayout>
-->
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
You could use CollectionView Grouping. https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/grouping
Xaml:
<CollectionView ItemsSource="{Binding Object1Collection}" IsGrouped="True">
<CollectionView.GroupHeaderTemplate>
<DataTemplate >
<Label Text="{Binding Response}"/>
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<CollectionView.ItemTemplate>
<DataTemplate>
<ScrollView>
<Grid Padding="10">
<StackLayout BackgroundColor="Blue">
<Label Text="{Binding Statistic}"/>
<Label TextColor="Black" Text=" : "></Label>
<Label Text="{Binding Amount}"/>
</StackLayout>
</Grid>
</ScrollView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Model:
public class Object1Model : List<Object2Model>
{
public string Response { get; set; }
public Object1Model(string response, List<Object2Model> Object2List) : base(Object2List)
{
Response = response;
}
}
public class Object2Model
{
public string Statistic { get; set; }
public string Amount { get; set; }
}
Code behind:
public ObservableCollection<Object1Model> Object1Collection { get; set; }
public Page23()
{
InitializeComponent();
Object1Collection = new ObservableCollection<Object1Model>();
Object1Collection.Add(new Object1Model("Object1A", new List<Object2Model>
{
new Object2Model(){ Statistic="Object2Statistic1A", Amount="Object2Amount1A"},
new Object2Model(){ Statistic="Object2Statistic1A", Amount="Object2Amount1A"},
}));
Object1Collection.Add(new Object1Model("Object1B", new List<Object2Model>
{
new Object2Model(){ Statistic="Object2Statistic1B", Amount="Object2Amount1B"},
new Object2Model(){ Statistic="Object2Statistic1B", Amount="Object2Amount1B"},
}));
Object1Collection.Add(new Object1Model("Object1C", new List<Object2Model>
{
new Object2Model(){ Statistic="Object2Statistic1C", Amount="Object2Amount1C"},
new Object2Model(){ Statistic="Object2Statistic1C", Amount="Object2Amount1C"},
}));
this.BindingContext = this;
}
Add ViewCell under DataTemplate of ListView.
<ListView Grid.Row="1" Grid.Column="1" ItemsSource="{Binding Object2List }">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Label TextColor="Black" Text="{Binding Statistic}"></Label>
<Label TextColor="Black" Text=" : "></Label>
<Label TextColor="Black" Text="{Binding Amount}"></Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Fix those two exceptions:
No viewcell error:
'Specified cast is not valid.'
Comment out the StackLayout error:
'LoadTemplate should not be null'

Row set in 'Auto' takes me all the screen even if it is blank

In a CollectionView I have 4 rows, 2 of which are set to "Auto".
In one I have a Label in Binding, in the other I have another CollectionView with objects in Binding. In the Row where I have the Label, the height is automatically set correctly, while where I have the CollectionView it becomes an "infinite" height, in the sense that even if empty, it takes up the whole screen.
<DataTemplate>
<yummy:PancakeView CornerRadius="5" BackgroundColor="Transparent">
<Grid BackgroundColor="Gainsboro" RowSpacing="0.2">
<Grid.RowDefinitions>
<RowDefinition Height="21"/>
<RowDefinition Height="16"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3"/>
<ColumnDefinition Width="65"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<BoxView Grid.Column="0" Grid.RowSpan="4" BackgroundColor="{Binding ColoreUmore}"/>
<Label Grid.Row="0" Grid.Column="2" Text="{Binding GiornoTrascritto}" FontSize="14" TextColr="Gray" Margin="0,5,0,0"/>
<Label Grid.Row="1" Grid.Column="2" Text="{Binding Orario}" FontSize="14" TextColr="Gray"/>
<Image Grid.Row="0" Grid.RowSpan="3" Grid.Column="1" Margin="8" Source="{Binding Umore}" VerticalOptions="Start" HeightRequest="45"/>
<Label Grid.Row="3" Grid.Column="2" TextColor="Black" FontSize="16" Text="{Binding Nota}" Margin="0,0,10,0" VerticalOptions="Start" HorizontalTextAlignment="Start" VerticalTextAlignment="Start"/>
<CollectionView
Grid.Row="2"
Margin="0,0,10,0"
Grid.Column="2"
SelectionMode="None"
ItemsSource="{Binding IconDiaries}"
VerticalOptions="Start">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" VerticalItemSpacing="5" HorizontalItemSpacing="5"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid RowSpacing="0.5">
<Grid.RowDefinitions>
<RowDefinition Height="17"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="18"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<BoxView BackgroundColor="Gray" Grid.ColumnSpan="2" Grid.Row="0" CornerRadius="5" Opacity="0.6" />
<Image Grid.Row="0" Grid.Column="0" Source="{Binding isSource}" Margin="3"/>
<Label Grid.Row="0" Grid.Column="1" Text="{Binding id}" TextColor="Black" FontSize="12" VerticalTextAlignment="Center" Margin="0,0,3,0"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</yummy:PancakeView>
</DataTemplate>
while where I have the CollectionView it becomes an "infinite" height, in the sense that even if empty, it takes up the whole screen.
From your code and description, you have one collectionview in datatemplate, now you want to adjust collectionview height according to its content, am I right?
If yes, I suggest you can binding collectionview HeightRequest like the following code:
<StackLayout >
<CollectionView
x:Name="assessmentsCollectionView"
BackgroundColor="Blue"
HeightRequest="{Binding rowHeigth}"
ItemsSource="{Binding letters}">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Padding="5" Spacing="10">
<Frame
Padding="0"
CornerRadius="5"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal">
<Frame
Padding="5"
CornerRadius="0"
WidthRequest="50">
<Label
FontSize="24"
HorizontalTextAlignment="Center"
Text="{Binding TypeLetter}"
TextColor="#37474f"
VerticalTextAlignment="Center" />
</Frame>
<StackLayout Padding="10">
<Label
FontSize="24"
Text="{Binding Name}"
TextColor="Black" />
<StackLayout Orientation="Horizontal">
<Image
HeightRequest="12"
Source="c1.png"
WidthRequest="12" />
<Label
FontSize="12"
Text="{Binding Date}"
TextColor="Gray" />
</StackLayout>
</StackLayout>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Button
x:Name="btn1"
Command="{Binding AddCommand}"
Text="btn1" />
</StackLayout>
public partial class Page4 : ContentPage
{
public Page4()
{
InitializeComponent();
this.BindingContext = new letterviewmodel(); ;
}
}
public class letterviewmodel: INotifyPropertyChanged
{
public ObservableCollection<lettermodel> letters { get; set; }
private int _rowHeigth;
public int rowHeigth
{
get { return _rowHeigth; }
set
{
_rowHeigth = value;
RaisePropertyChanged("rowHeigth");
}
}
public ICommand AddCommand { protected set; get; }
public letterviewmodel()
{
letters = new ObservableCollection<lettermodel>()
{
new lettermodel(){TypeLetter="A",Name="letter 1",Date="2021-01-01"},
new lettermodel(){TypeLetter="B",Name="letter 2",Date="2021-01-01"},
new lettermodel(){TypeLetter="C",Name="letter 3",Date="2021-01-01"}
};
rowHeigth = letters.Count * 100 ;
AddCommand = new Command<lettermodel>(async (key) => {
letters.Add(new lettermodel() { TypeLetter = "D", Name = "test letter ", Date = "2021-01-01" });
rowHeigth = letters.Count * 100 ;
});
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class lettermodel
{
public string TypeLetter { get; set; }
public string Name { get; set; }
public string Date { get; set; }
}
The screenshot:
If I understand correctly, you want the CollectionView to take an automatic height and adapt to the row, right?
In order to make this happen you will need to:
Set the property
ItemSizingStrategy="MeasureFirstItem" in the CollectionView, so the CollectionView has the proper height you're looking for.
Set the Row Height to *, so the CollectionView height sets automatically for the remaining size of the page.
Set VerticalOptions to FillAndExpand in Collection View so the CollectionView can adapt to the size of the Row.
Finally, put the label with Row 3 below the CollectionView to avoid any issues with the Layout order.
Let me know if this does any help!

Xamarin.Forms (PRISM) - Bind checkbox, to a command in viewmodel, outside listview itemsource

Sooo, im building a Prism, xamarin.forms app.
I have a object by the name of "Herd", with basic attributes.
Im displaying a list of these objects, and want to activate a command that sends the herd that is checked in a checkbox to the viewmodel.
<ListView
x:Name="UpdateHerdList"
ItemsSource="{Binding HerdsThatsNeedsToBeUpdated}"
RowHeight="60"
>
<ListView.ItemTemplate>
<DataTemplate>
<CustomRenderer:TransparentViewCell>
<Grid
>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Label
TextColor="Black"
FontSize="15"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Start"
Grid.Column="0"
Text="{Binding HeaderName}"
/>
<CheckBox
Grid.Column="1"
HorizontalOptions="Center"
ScaleX="1.75"
ScaleY="1.75"
Color="Black"
IsChecked="True"
>
<CheckBox.Behaviors>
<b:EventToCommandBehavior
EventName="PropertyChanged"
Command="{Binding UpdateThisHerdCommand}"
CommandParameter="{Binding Herd}"
/>
</CheckBox.Behaviors>
</CheckBox>
</Grid>
</CustomRenderer:TransparentViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
But i cant seem to find the right way to bind to the viewmodel inside the itemsource of the listview.
Can someone please help guiding me to the right binding.
Thanks in advance!
About binding one command to checkbox, I do one sample that you can see the following code. If you change checkbox checked, will pass current listview item.
<ListView
x:Name="UpdateHerdList"
ItemsSource="{Binding HerdsThatsNeedsToBeUpdated}"
RowHeight="60">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Label
Grid.Column="0"
FontSize="15"
HorizontalTextAlignment="Start"
Text="{Binding HeaderName}"
TextColor="Black"
VerticalTextAlignment="Center" />
<CheckBox
Grid.Column="1"
HorizontalOptions="Center"
IsChecked="True"
ScaleX="1.75"
ScaleY="1.75"
Color="Black">
<CheckBox.Behaviors>
<b:EventToCommandBehavior
Command="{Binding BindingContext.UpdateThisHerdCommand, Source={x:Reference UpdateHerdList}}"
CommandParameter="{Binding .}"
EventName="CheckedChanged" />
</CheckBox.Behaviors>
</CheckBox>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
public partial class Page34 : ContentPage
{
public ObservableCollection<Herd> HerdsThatsNeedsToBeUpdated { get; set; }
public ICommand UpdateThisHerdCommand { get; set; }
public Page34()
{
InitializeComponent();
HerdsThatsNeedsToBeUpdated = new ObservableCollection<Herd>()
{
new Herd(){HeaderName="test 1"},
new Herd(){HeaderName="test 2"},
new Herd(){HeaderName="test 3"},
new Herd(){HeaderName="test 4"},
new Herd(){HeaderName="test 5"},
new Herd(){HeaderName="test 6"}
};
UpdateThisHerdCommand = new Command<Herd>(checkboxcommand);
this.BindingContext = this;
}
private void checkboxcommand(Herd herd)
{
Console.WriteLine("the selected item is {0}",herd.HeaderName);
}
}
public class Herd
{
public string HeaderName { get; set; }
}

Select the CardView in Xamarin

In my Xamarin, I have two CardView (https://github.com/tiger4589/Xamarin.Forms-CardView) within separate Grid.Column.
What I want to do is select a CardView (one at a time), which enables the Button.
How could I acheive this?
.xml code for CardView
<Grid Grid.Column="0">
<cardView:CardView>
<cardView:CardView.CardViewContent>
<StackLayout>
<Label
Text="PIN"
FontSize="18"
HorizontalTextAlignment="Center">
</Label>
</StackLayout>
</cardView:CardView.CardViewContent>
</cardView:CardView>
</Grid>
<Grid Grid.Column="1">
<cardView:CardView>
<cardView:CardView.CardViewContent>
<StackLayout>
<Label
Text="QR Scan"
FontSize="18"
HorizontalTextAlignment="Center">
</Label>
</StackLayout>
</cardView:CardView.CardViewContent>
</cardView:CardView>
</Grid>
.xml code for Button
<Button
x:Name="FormButton"
IsEnabled="False"
TextColor="#4DABFE"
Text="Submit">
</Button>
UPDATE ON CollectionView
<StackLayout>
<Frame >
<CollectionView ItemsSource="{Binding .}"
SelectionMode="Single">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal">
<Label Text="Tokyo"
FontSize="20"
TextColor="Orange"
VerticalOptions="Center" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Frame>
</StackLayout>
your collectionview would look like this
<CollectionView x:Name="MyCollection"
SelectionMode="Single">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Title}"
FontSize="20"
TextColor="{Binding ItemColor}"
VerticalOptions="Center" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Now you need to create a model Eg. MyDataModel which would have property as follow
class MyDataModel
{
public int ItemId{ get; set; }
public string Title { get; set; }
public string ItemColor { get; set; }
}
now you need to init the list in your .cs file also u can do this view viewmodel but in your case you are using .cs
so it would look something like this in your constructor
var myList = new List<MyDataModel>();
Loop your XmlData List
eg. XmlDataList.ForEach((item)=>{ myList.Add(new MyDataModel{Title = item.properyinxml
})});
MyCollection.ItemSource = myList;

how to display different content for each view in carouselview xamarin.forms

here is my initial code
<CarouselView x:Name="BGcarousel" >
<CarouselView.ItemTemplate>
<DataTemplate>
<Grid RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Grid.Column="0"
Source="{Binding BackgroundImage}"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Aspect="AspectFill" />
<Frame
Grid.Row="0"
Grid.Column="0"
VerticalOptions="Center"
HorizontalOptions="Center"
HeightRequest="30"
WidthRequest="120"
CornerRadius="60"
HasShadow="True"
BackgroundColor="BlueViolet">
<Label
Text="{Binding Icon}"
TextColor="Black"
VerticalOptions="Center"
HorizontalOptions="Center"
FontAttributes="Bold"
FontSize="23"
Padding="0" />
</Frame>
<Label Grid.Row="0" Grid.Column="0"
Text="{Binding Quot}"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
HorizontalTextAlignment="Center"
VerticalTextAlignment="End"
Padding="0,0,0,50"
TextColor="White"
FontSize="30"/>
</Grid>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
this looks like every page would have the same content but I need to add a button in only the last and control its behaviors
Microsoft has just added a carouselview as a feature and I am new to this
anyone can help me
Solution 1:If you want to use other different layouts for each view in carouselview xamarin.forms, I advice you to use DataTemplateSelector to achieve it.
First of all, you can create two DataTemplate for your CarouselView(You can create lots of DataTemplates, If you want to do).
<ContentPage.Resources>
<DataTemplate x:Key="AmericanMonkeyTemplate">
<StackLayout>
<Frame HasShadow="True"
BorderColor="DarkGray"
CornerRadius="5"
Margin="20"
HeightRequest="300"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand">
<StackLayout>
<!--Add layout that you want-->
<Label Text="{Binding Name}"
FontAttributes="Bold"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Label Text="{Binding Location}"
HorizontalOptions="Center" />
<Label Text="{Binding Details}"
FontAttributes="Italic"
HorizontalOptions="Center"
MaxLines="5"
LineBreakMode="TailTruncation" />
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
<DataTemplate x:Key="OtherMonkeyTemplate">
<!--Add layout that you want-->
<StackLayout>
<Frame HasShadow="True"
BorderColor="DarkGray"
CornerRadius="5"
Margin="20"
HeightRequest="300"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand">
<StackLayout>
<Label Text="{Binding Name}"
FontAttributes="Bold"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Label Text="{Binding Location}"
HorizontalOptions="Center" />
<Label Text="{Binding Details}"
FontAttributes="Italic"
HorizontalOptions="Center"
MaxLines="5"
LineBreakMode="TailTruncation" />
<Button
Text="Click"
/>
<Button
Text="Click"
/>
<Button
Text="Click"
/>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
<controls:MonkeyDataTemplateSelector x:Key="MonkeySelector"
AmericanMonkey="{StaticResource AmericanMonkeyTemplate}"
OtherMonkey="{StaticResource OtherMonkeyTemplate}" />
</ContentPage.Resources>
<StackLayout>
<CarouselView ItemsSource="{Binding Monkeys}" ItemTemplate="{StaticResource MonkeySelector}">
</CarouselView>
</StackLayout>
</ContentPage>
then create an DataTemplateSelector, you can depend an property to show which DataTemple layout. For example, If Location is Eurp, I set it to OtherMonkey DataTemple, others set America DataTemple.
public class MonkeyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate AmericanMonkey { get; set; }
public DataTemplate OtherMonkey { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
return ((Monkey)item).Location.Contains("Eurp") ? OtherMonkey : AmericanMonkey;
}
}
Solution 2 Agree with Jason, you can use IsVisible for button, binding an property with ButtonIsVisable like following code.
<Button
Text="Click"
IsVisible="{Binding ButtonIsVisable}"
/>
Then add ButtonIsVisable Property in your Model.
public class Monkey
{
public string Name { get; set; }
public string Location { get; set; }
public string Details { get; set; }
public bool ButtonIsVisable { get; set; }
}
In the ViewModel, you can control the Button if is visable or not.
public class MyViewModel
{
public ObservableCollection<Monkey> Monkeys { get; set; }
public MyViewModel()
{
Monkeys =new ObservableCollection<Monkey>();
Monkeys.Add(new Monkey() { ButtonIsVisable=false, Details="Details1", Location="Usa", Name="Test1" });
Monkeys.Add(new Monkey() { ButtonIsVisable = false, Details = "Details2", Location = "Asia", Name = "Test2" });
Monkeys.Add(new Monkey() { ButtonIsVisable = true, Details = "Details3", Location = "Eurp", Name = "Test3" });
}
}
In the layout add the button.
<CarouselView ItemsSource="{Binding Monkeys}">
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame HasShadow="True"
BorderColor="DarkGray"
CornerRadius="5"
Margin="20"
HeightRequest="300"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand">
<StackLayout>
<Label Text="{Binding Name}"
FontAttributes="Bold"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Label Text="{Binding Location}"
HorizontalOptions="Center" />
<Label Text="{Binding Details}"
FontAttributes="Italic"
HorizontalOptions="Center"
MaxLines="5"
LineBreakMode="TailTruncation" />
<Button
Text="Click"
IsVisible="{Binding ButtonIsVisable}"
/>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
Here is layout background code.
public MainPage()
{
InitializeComponent();
this.BindingContext = new MyViewModel();
}
Here is running GIF.

Categories