Slow ScrollView performance in Xamarin.Forms and WinPhone Silverlight - xamarin

I´m facing a bad performance using all sort of layouts (e.g. StackLayout, Grid) inside a ScrollView specifically on the WP SL platform. On the other platforms (Android and iOS) the performance is way better using the same layout. I´m using the latest stable version of Xamarin.Forms (2.3.1.114) at the moment. Has anyone faced this issue too?
Thanks.
UPDATE: Code sample added to better understanding. The layout itself is not complex.
<ScrollView>
<StackLayout BackgroundColor="Black" Padding="5" Spacing="20" >
<StackLayout>
<Label Text="User name:" />
<Label Text="{Binding LoggedInUser}" />
</StackLayout>
<StackLayout>
<Label FontSize="Medium" FontAttributes="Bold" TextColor="Gray" Text="Help" />
<BoxView HeightRequest="1" BackgroundColor="Gray" HorizontalOptions="Fill" />
<Label FontSize="Small" FontAttributes="Bold" TextColor="Gray" Text="Please, send an email to xxx#example.com" />
</StackLayout>
</StackLayout>
</ScrollView>

Related

Xamarin Forms Tabs with a Button

I'm trying to make a design like in the picture
But I don't know how to make tab buttons and tab process. I read microsoft's articles and watched a few videos.but none of them were as I wanted.I would be glad if you help
Yes, you can try to use Xamarin Community Toolkit TabView to achieve this just as Jason mentioned.
You can customize your tab to your needs.
Please refer to the following code:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
x:Class="MyLittleApp.MainPage">
<Grid>
<xct:TabView
TabStripPlacement="Bottom"
TabStripBackgroundColor="Blue"
TabStripHeight="60"
TabIndicatorColor="Yellow"
TabContentBackgroundColor="Yellow">
<xct:TabViewItem
Icon="triangle.png"
Text="Tab 1"
TextColor="White"
TextColorSelected="Yellow"
FontSize="12">
<Grid
BackgroundColor="Gray">
<Label
HorizontalOptions="Center"
VerticalOptions="Center"
Text="TabContent1" />
</Grid>
</xct:TabViewItem>
<xct:TabViewItem
Icon="circle.png"
Text="Tab 2"
TextColor="White"
TextColorSelected="Yellow"
FontSize="12">
<Grid>
<Label
HorizontalOptions="Center"
VerticalOptions="Center"
Text="TabContent2" />
</Grid>
</xct:TabViewItem>
</xct:TabView>
</Grid>
</ContentPage>
Note:You can also check thread: Custom TabbedPage with buttons .

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>

Entry with Icon at the right side

Is there a way to achieve this entry plus an icon at xamarin forms, without going through platform specific effects/renders, cause right now in order to achieve this, I have implemented a platform effect for this. Please check the image link below:
EntryImage
EDIT1: Changed link
For anyone who is wondering how I used #Alessandro 's answer, here's how it is.
<StackLayout Orientation="Vertical" VerticalOptions="CenterAndExpand">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Entry Placeholder="Test"
Text="Test"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
/>
<Image Source="test_image.png"
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="1"
HorizontalOptions="End">
</StackLayout>
I think the best solution is to create a Grid with 1 rows and 2 columns.
In column 0 you add your Entry and in column 1 you add your icon. If you want you can set your Entry to occupy column 1 and 2
Entry with Icon at the right side
<StackLayout Orientation="Horizontal" Spacing="0">
<Entry IsPassword="True" HorizontalOptions="FillAndExpand"/>
<Image Source="icon.png" WidthRequest="50" HeightRequest="50"/>
</StackLayout>

Small Xamarin.Forms app throws OutOfMemoryException on Android

I have a small web app for sending texts between web and mobile - I wanted to create a mobile apps for this web app and decided to go with Xamarin instead of learning both Java and Swift. I bought courses and learned how yo use Xamarin.Forms and I built my first Alpha version (which already released it to the Play Store and the App Store version is in the Review progress).
All the development progress went very well on the Emulator with no issues, but once I downloaded the app to my Nexus 6P (which is a super phone) - after moving between sections on the app, the app stopped. I debugged it and found that it is closing because of OutOfMemoryException. The app only have very few sections with a ListView (I realized that the issue with the ListView which somehow makes the app stop running - while it is running very well on the emulator).
My ViewModels read the data from the server (using HttpClient) and creates the ObservableCollection which is binded to the views. My issue is with the ListView which makes all the problem with the OutOfMemory:
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame HasShadow="False" OutlineColor="White" Padding="10, 10, 10, 20" VerticalOptions="Center">
<Frame.Content>
<Frame OutlineColor="Gray" VerticalOptions="Center">
<Frame.HasShadow>
<OnPlatform x:TypeArguments="x:Boolean" Android="True" WinPhone="True" iOS="False" />
</Frame.HasShadow>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Grid.Row="0" FontSize="Small"
Text="{Binding Paste.Text}" />
<Grid Grid.Row="1" Padding="0, 20, 0, 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ffimageloading:CachedImage x:Name="btnCopy" Grid.Column="0" DownsampleToViewSize="true" Scale="0.8" Source="copy.png">
<ffimageloading:CachedImage.GestureRecognizers>
<TapGestureRecognizer Command="{Binding CopyToClipboardCommand, Source={x:Reference pastesPage}}" CommandParameter="{Binding .}" />
</ffimageloading:CachedImage.GestureRecognizers>
</ffimageloading:CachedImage>
<StackLayout Grid.Column="1">
<ffimageloading:CachedImage x:Name="btnFavourite" DownsampleToViewSize="true"
IsVisible="{Binding ShowFavouriteButton}"
Scale="0.8"
Source="{Binding FavouriteImage}">
<ffimageloading:CachedImage.GestureRecognizers>
<TapGestureRecognizer Command="{Binding BindingContext.ChangePasteFavouriteCommand, Source={x:Reference pastesPage}}" CommandParameter="{Binding .}" />
</ffimageloading:CachedImage.GestureRecognizers>
</ffimageloading:CachedImage>
<ActivityIndicator IsRunning="{Binding IsFavouriteRunning}"
IsVisible="{Binding IsFavouriteRunning}"
Scale="0.7" Color="Gray" />
</StackLayout>
<StackLayout Grid.Column="2">
<ffimageloading:CachedImage x:Name="btnDelete" DownsampleToViewSize="true"
IsVisible="{Binding ShowDeleteButton}"
Scale="0.8" Source="delete.png">
<ffimageloading:CachedImage.GestureRecognizers>
<TapGestureRecognizer Command="{Binding BindingContext.DeletePasteCommand, Source={x:Reference pastesPage}}" CommandParameter="{Binding .}" />
</ffimageloading:CachedImage.GestureRecognizers>
</ffimageloading:CachedImage>
<ActivityIndicator IsRunning="{Binding IsDeleteRunning}"
IsVisible="{Binding IsDeleteRunning}"
Scale="0.7" Color="Gray" />
</StackLayout>
<ffimageloading:CachedImage x:Name="btnShare" Grid.Column="3" DownsampleToViewSize="true" Scale="0.8" Source="share.png">
<ffimageloading:CachedImage.GestureRecognizers>
<TapGestureRecognizer Command="{Binding SharePasteCommand, Source={x:Reference pastesPage}}" CommandParameter="{Binding .}" />
</ffimageloading:CachedImage.GestureRecognizers>
</ffimageloading:CachedImage>
</Grid>
</Grid>
</Frame>
</Frame.Content>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
The icons are very small png files. This list is not large and I don't think that a small ListView should throw such an exception. What is wrong here? How can I fix this issue?
I tried to remove the icons and the same issue happen, I tried to change the icons from images to a FontAwesome icons but the app stopped very quickly. I even tried to use the ChacheImages plugin but with no help.
Here is an image of the list that is produced:
Any suggestions?
Thanks,
Seif.
The key part you mentioned is that this occurs after moving through the different sections of your app. This implies you have a memory leak somewhere which gets triggered by navigation.
One common cause is subscribing to events on page appear and never unsubscribing or otherwise keeping whole pages in memory while the navigation code keeps creating new page instances.
Without looking at all of your code, it's hard to say exactly where the problem is.
Also note that your XAML is way too complex. You should always strive to keep control nesting as low as possible. Yet here you have two frames, two grids and stack layouts, all nested. This is terrible for your app performance. Please consider simplifying your layout. There's numerous techniques to accomplish this. Whenever you can, use a simple AbsoluteLayout and proportionally size the controls as needed to display your data.

Silverlight user control vanishes in designer

I am writing an application in Silverlight that is supposed to retrieve weather data from Google and then display it. I was working on the layout in XAML and was going to see how it looked in the designer, but when I switched to the designer pane, a small notice said that an assembly had been updated, so I clicked it, and the user control vanished! I've been trying to remove parts of recent markup but it doesn't seem to help. Here is the XAML for the main user control:
<UserControl x:Class="TestApp2.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
xmlns:wtb="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Extended"
xmlns:local="clr-namespace:TestApp2"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="#FF5e59e4">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Grid.Row="0" Grid.Column="0" Margin="5" CornerRadius="5" Background="AliceBlue">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="70" />
</Grid.ColumnDefinitions>
<Border Grid.Row="0" Grid.Column="0" Margin="3" Style="{StaticResource RoundedBox}" >
<TextBlock x:Name="TextBox" Text="Weather Finder" Margin="5,0,0,0" FontSize="18" VerticalAlignment="Center"/>
</Border>
<wtb:WatermarkedTextBox Grid.Row="0" Grid.Column="1" Watermark="City..." Margin="2,4,2,4" />
<Button x:Name="SearchButton" Grid.Row="0" Grid.Column="3" Content="Search" VerticalAlignment="Center" Margin="2,0,2,0" />
<!--<ListBox x:Name="DataList" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" Margin="3,0,3,3" />-->
<StackPanel Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" Margin="3,0,3,3" Orientation="Vertical">
<local:WeatherBox x:Name="Cur" HorizontalAlignment="Center" />
<StackPanel Orientation="Horizontal">
<local:WeatherBox x:Name="Day1" HorizontalAlignment="Center" />
<local:WeatherBox x:Name="Day2" HorizontalAlignment="Center" />
<local:WeatherBox x:Name="Day3" HorizontalAlignment="Center" />
<local:WeatherBox x:Name="Day4" HorizontalAlignment="Center" />
</StackPanel>
</StackPanel>
</Grid>
</Border>
</Grid>
</UserControl>
I have yet to write any functionality into the application, so that can't be the problem. I believe it might have something to do with my own WeatherBox (if anyone wants to see the code for it say so), but removing them from the code didn't work. What could be wrong?
I think I might have discovered one reason for the problems. This line of XAML in the WeatherBox control gets an exception when I run the application:
<BitmapImage UriSource="{Binding Thumbnail, Converter={StaticResource BitmapImageConverter}}" />
As far as I understood, it's not possible place use a binding directly in the UriSource, so I tried to use a converter. It seemed to work in the editor, but not when running. I still have no idea of what's wrong.
This happens all the time with custom controls you design. At the moment the visual studio designer support is incredibly flaky (silverlight 2 & 3 beta with visual studio 2008). It will have a huff at the slightest of thing and will never tell you why. At least you're not getting the COM error.
The easiest way to find out the control that is causing it is to start commenting out swathes of your XAML until you identify the control by elimination.
Usually it will be one of your own controls and it will be doing it because you're trying to download some data from a website or web service, which it can't do in designer mode. All you need to do is detect if it's in design mode and skip the code if it is.
Here's a post abut detecting design mode: http://blogs.sqlxml.org/bryantlikes/archive/2009/02/25/detecting-design-mode-in-silverlight.aspx
The binding error isn't the cause, though it shouldn't be ignored. It means an object you've bound to doesn't have the property you're trying to access.

Resources