List of ContentViews in a CarouselView with PullToRefresh - xamarin

I have a list of two ContentViews that have the PullToRefreshLayout plugin within them surrounding ScrollViews. I'm not sure what's going on, but when you pull to refresh, the refresh circle appears but the Refresh Command never gets hit nor does the refresh circle ever finish.
Here is my CarouselView
<cv:CarouselView
Margin="0, 0, 0, 0"
ItemsSource="{Binding ContentViews}"
Position="{Binding CarouselPosition}"
x:Name="ContentCarousel">
<cv:CarouselView.ItemTemplate>
<DataTemplate>
<ContentView Content="{Binding Content}"/>
</DataTemplate>
</cv:CarouselView.ItemTemplate>
</cv:CarouselView>
And here is an example of one of my ContentViews.
<ContentView.Content>
<controls:PullToRefreshLayout
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding BindingContext.RefreshReceivingCommand, Source={x:Reference Name=ReceivingContentView}}"
IsRefreshing="{Binding IsBusy}"
RefreshColor="#4ABDAC">
<ScrollView
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Style="{StaticResource cardScrollViewBackgroundColor}">
<StackLayout
Padding="0,0,0,0"
VerticalOptions="StartAndExpand"
x:Name="MainStackLayout">
</StackLayout>
</ScrollView>
</controls:PullToRefreshLayout>
</ContentView.Content>
I'm honestly not sure what's going on. I have tried different binding contexts on the refresh command but the command is never hit. Any ideas is greatly appreciated!
EDIT: I sorta found a solution but not a huge fan.
I created an empty Constructor in my ViewModel that sets my Refreshing Commands. Then in the ContentView, I sent the BindingContext to the ViewModel. Seems redundant, but eh, works for now until I figure out the xaml binding.

Related

Object retain in memory when click on listview headertemplate in iOS device

I am developing an enterprise application using Xamarin.Forms. I am facing a memory leak issue in iOS specifically (working fine in Android).
Its regarding click over listview item header, I implemented gestures, then a transparent button as well, but it causes a memory leak - even if I comment out its functionality.
If I comment testbutton then its objects are disposing fine. What can I do to fix this issue?
```
<ListView
Style="{DynamicResource BaseListViewStyle}"
IsGroupingEnabled="True"
ItemsSource="{Binding Deliveries.ExpandedDeliveryItemModels}"
IsPullToRefreshEnabled="True"
IsRefreshing="{Binding Deliveries.IsRefreshing}"
RefreshCommand="{Binding RefreshCommand}"
SelectionMode="None">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell AutomationId="headerCell">
<StackLayout AutomationId="headerLayout" Orientation="Horizontal">
<Label Text="{Binding HeaderTitle}"
AutomationId="DeliveriesToday"
HorizontalOptions="StartAndExpand">
</Label>
<Button x:Name="testbutton"
HorizontalOptions="End"
Command="{Binding Source={x:Reference deliveriesPage}, Path=BindingContext.HeaderClickCommand}"
CommandParameter="{Binding .}">
</Button>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell AutomationId="deliveriesCell">
<Label Text="Testing"></Label>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
```
Welcome to SO !
You can have a try with modifying CachingStrategy of ListView , there are three types of CachingStrategy value.
RecycleElement 1 Indicates that unneeded cells will have their binding contexts updated to that of a cell that is needed.
RecycleElementAndDataTemplate 3 Indicates that, in addition to the behavior specified by RecycleElement, DataTemplate objects that are selected by a DataTemplateSelector are cached by the data template type.
RetainElement 0 Indicates that for every item in the List View's ItemsSource property, a single unique element will be constructed from the DataTemplate.
The deflault value is RetainElement, the behavior is to retain item data in their generated cells when they are not needed.
For performance reasons, it is likely that the default behavior will be changed to RecycleElement in a future release. In the meantime, for memory and performance reasons, app developers should specify RecycleElement when constructing a new List View.
Therefore , you can modify code as follow :
<ListView CachingStrategy="RecycleElement" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<!-- ... -->
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Placing a ListView together with a VideoView add several blank lines between them

I created a page in Xamarin.Forms that should display some items, coming from an IList data source, and a video after them.
List of items will be displayed using ListView. The video is displayed using VideoView.
This is the actual page code:
<?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:mm="clr-namespace:Plugin.MediaManager.Forms;assembly=Plugin.MediaManager.Forms"
x:Class="MyApp.Views.ItemDetailPage"
Title="{Binding Title}">
<ScrollView>
<StackLayout Orientation="Vertical" Padding="15">
<ListView
ItemsSource="{Binding Item.Properties}"
HasUnevenRows="true">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="10">
<Label Text="{Binding .}"
LineBreakMode="NoWrap"
Style="{DynamicResource ListItemTextStyle}"
FontSize="16" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<mm:VideoView x:Name="MyVideo" WidthRequest="320" HeightRequest="190" HorizontalOptions="FillAndExpand" />
<Button x:Name="BtnPlayStop" Text="Iniciar" Clicked="PlayStop_Clicked" BackgroundColor="Silver" TextColor="White"/>
</StackLayout>
</ScrollView>
</ContentPage>
The problems I have when I run the app are:
The page initially appears scrolled down so that the video is initially seen.
The space between the last element of the list view and the video is very big
It´s difficult to do the scroll up or down by using the finger.
Is my XAML code correct? what changes can I apply to fix this weird behaviour?
EDIT: I have found that between the listview and video is nothing. That is why it is difficult to scroll. If I place the finger inside the list view, I can scroll, the same if I place the finger inside the video or button. But if I place the finger between the list view and the video no scroll is performed. Weird, isn't it?
Thanks
Jaime
Finally, I have used solution in this page: https://xamarinsharp.com/2017/05/16/listview-height-issue-in-xamarin-forms-how-to-solve-it/
Basicly, it is to set the HeightRequest of the ListView in code behind according to the number of bound elements.
Regards
Jaime

Xamarin Forms: handle multiple item per row

In Xamarin Forms i want show multiple image (2) in a row: this is an example of what i'd like to do:
In many Q&A i've seen the use of XLabs gridview but the project is no longer maintained.
I think that i can create a custom cell with a stacklayout inside a row but the recycle policy work? And how can i handle the item tapped if i have two column per row?
Thanks
Alessandros answer should work, but if you want to roll something yourself without any third party controls, keep reading:
Recycling will still work if you use a Custom ViewCell. So I would suggest doing that and adding two items in a custom model and render them in one cell at a time.
Now for handling taps: Override the ItemSelected event on your ListView and set the ListView.SelectedItem to null. Then inside your custom ViewCell, add a TapGestureRecognizer to each of the separate models. One thing to note, is that the Command on your TapGestureRecognizer will bind to your individual list item, so you need to set it relative to the BindingContext of the ListView:
<ListView x:Name="MyListView" ...>
<ListView.ItemTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal>
<Image ...>
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={x:Reference MyListView}, Path=BindingContext.Item1Command}"/>
</Image.GestureRecognizers>
</Image>
<Image ...>
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={x:Reference MyListView}, Path=BindingContext.Item2Command}"/>
</Image.GestureRecognizers
</Image>
</StackLayout>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You can take a look to this FlowListView.
I have never used it but sounds good.
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
<Label HorizontalOptions="Fill" VerticalOptions="Fill"
XAlign="Center" YAlign="Center" Text="{Binding Title}"/>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>

Apply animation inside DataTemplate

I have a listbox with the following structure. Data displays well and no issues there. I want to get some animation affect for the StackPanel, but since it is inside the DataTemplate, I am not able to use Blend to get my desired animation affect.
I guess I can write an event handler and code for that, but is that the best approach of achieving animation for ListBox items?
<ListBox Height="600" ItemsSource="{StaticResource learn}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Height="100" Orientation="Horizontal">
<TextBlock Width="0" Text="{Binding ID}" />
<Image Height="100" Width="100"/>
<StackPanel Orientation="Vertical" Width="319" VerticalAlignment="Center">
<TextBlock TextWrapping="Wrap" Text="{Binding Text}" Margin="6,0,0,0" FontSize="29.333" />
<TextBlock TextWrapping="Wrap" Text="{Binding Description}" Margin="6,0,0,0" FontSize="16"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Okay, all you need to do is to create a new user control and add all your animations to that user control and start animation where you want. In the list box data template, create an instance of that data template.
Steps to reproduce:
Create a new User Control in the project.
Give in the animations to the animations to that user control in blend.
Add the user control in data template.
Start the animations where ever you want.
Alternative: Without creating a new user control you can specify animations by creating storyboard and applying required transformations. this gives a common animation to all the list box items.

Windows Phone 7 Linking to events inside DataTemplates

I have a listbox where I create a Itemtemplate with a DataTemplate. I want to be able to write events for the checkboxes and buttons in the datatemplate but they do not seem to be firing.
Here is my xaml and basically I just tried to display a messagebox.show("worked") in the event function.
<ListBox x:Name="ListBox_Items" Margin="0,91,0,8" Foreground="#FF4BE5DB">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Width="700">
<CheckBox IsChecked="{Binding needPurchase}" Click="NeedPurchase_Click" Name="CheckBox_NeedPurchase"/>
<CheckBox IsChecked="False" Name="InCart"/>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding name}"/>
<TextBlock Text="{Binding storeLocation}"/>
</StackPanel>
<Button HorizontalAlignment="Right" Content="DELETE" Click="Button_Click" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Because the items are defined within a DataTemplate they are not hooked up to the code-behind for the parent class. If you want to handle events for templated items, then you should consider using commands instead. If you don't know what commands are (and therefore unlikely to know what MVVM is), then you should check out an explanation like this by Jeremy Likness.
I agree that using commands is the best approach.
However if you still want to assess controls placed inside the ItemTemplate/DataTemplate (and subscribe to some events), then you can do this by using the VisualTreeHelper.
For starters you need to remove the name from all the controls in the template. If you have 10 items in the list you will have 10 sets of controls with the same name which won't work.

Resources