memory cleanup issue inside listbox / detaching the trigger issue - windows-phone-7

<listbox>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="120" Width="480" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="110"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border
Height="105"
Width="110"
BorderBrush="White"
Grid.Column="0"
BorderThickness="2">
<Image
delay:LowProfileImageLoader.UriSource="{Binding Path=Avatar}"
Source="/Image/default-thumb-groups.png">
</Image>
</Border>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="4"/>
<RowDefinition Height="35"/>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Text="{Binding Path=Name,Mode=TwoWay}"
Grid.Column="1"
Grid.Row="1"
FontFamily="Segoe WP Light"
FontSize="26"
Foreground="{StaticResource PhoneForegroundBrush}"
TextWrapping="Wrap">
</TextBlock>
<TextBlock
Text="{Binding Path=Members,Mode=TwoWay}"
Grid.Column="2"
Grid.Row="2"
FontFamily="Segoe WP Light"
HorizontalAlignment="Left"
FontSize="20" Opacity="0.91"
Foreground="{StaticResource PhoneForegroundBrush}"
TextWrapping="Wrap">
</TextBlock>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu
Name="DeleteGroup"
IsZoomEnabled="False"
Tag="{Binding Nid,Mode=TwoWay}"
Visibility="{Binding ElementName=GroupList, Path=DataContext.DeleteStatus,Mode=TwoWay, Converter=
{StaticResource booleanToVisibility}}" Opened="DeleteGroup_Opened" Closed="DeleteGroup_Opened">
<toolkit:MenuItem Header="delete group">
<Interactivity:Interaction.Triggers>
<Interactivity:EventTrigger EventName="Click">
<Command:EventToCommand Command="{Binding ElementName=GroupList,
Path=DataContext.DeleteCommand,Mode=TwoWay}" CommandParameter="{Binding
ElementName=DeleteGroup}" PassEventArgsToCommand="True"/>
</Interactivity:EventTrigger>
</Interactivity:Interaction.Triggers>
</toolkit:MenuItem>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
While trying for cleanup ; The Trigger of Context menu is not Detaching ; Because of this that page is not Dying even after navigating back from the page. This causing Saviour memory issue in our page. Please help me to resolve this Issue

Never worked with the Toolkit ContextMenu, but noticed that you are not the only one having similar problem. For example this article proves that "the ContextMenu control attaches itself to the RootVisual via mouse event handlers and therefore never gets GC'ed; even worse, the visual tree it is placed in is kept alive as well". Even if that article talks about the desktop, the symptoms are probably the same on WP7.
I would try to create/destroy menu programatically. This article demonstrates the techniques that can be used.
Another possibility would be to customize the listbox:
Override PrepareContainerForItemOverride: Call base.PrepareContainerForItemOverride() to get the standard ListBoxItem and add ContextMenu to it manually.
Override ClearContainerForItemOverride to clear the menu reference.
(Never tried that, but it should work.)
A side remark
Your Xaml seems to be overcomplicated to me. If nothing else, then using nested grids within ListBoxItem (which in turn is embedded into ListBox panel (VirtualizingStackPanel), which is in at least one more panel on the page level) must have terrible perf impact.
Even if I forget that the internal 4x2 grid uses 2 cells only (perhaps you simplified presented Xaml), what's the purpose of the outer grid? The same effect can be achieved by using a single grid and column span over the first column.

Related

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.

ExpanderView Interactive item within header

I want to have some interactive item I can click and fire event within header of ExpanderView. This is a normal behavior for item, but I cannot get it working in header.
In my case I have Image with MouseLeftButtonDown
Any ideas ?
Thanks,
Michal
You can change the look and content of the header by changing the HeaderTemplate of the ExpanderView. The HeaderTemplate takes a DataTemplate which can take any controls you which to place.
<toolkit:ExpanderView>
<toolkit:ExpanderView.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding}"/>
<Button Content="Click Me!" Grid.Column="1"
<!-- Use click event to handle within code behind -->
Click="OnHeaderBuittonclick"
<!-- Use command to handle within view model -->
Command="{Binding DoSomethingCommand}"
/>
</Grid>
</DataTemplate>
</toolkit:ExpanderView.HeaderTemplate>
</toolkit:ExpanderView>

Telerik RadSlideView (WP7) with MVVM

I'm currently trying to use Telerik's RadSlideView to display my images. I've followed the code in http://www.telerik.com/help/windows-phone/radslideview-gettingstarted.html and they work perfectly well, but on the other hand I'd like to bind to real objects (with a variety of properties) and not just string arrays.
My main reason for wanting to do this is to allow the RadSlideView to show more than just images. I'd like to have descriptions, and other stuff! (which all belong to a specific object) I know this question might be kinda obscure, but if you could give me any ideas, it'd help me a long way :) cheers.
In the page you linked there's a sample with "complex" databinding, look at the ItemTemplate property where there's the image with a description :
<telerikPrimitives:RadSlideView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Title}" FontSize="{StaticResource PhoneFontSizeExtraLarge}"/>
<Image Source="{Binding ImagePath}" Stretch="None" Grid.Row="1" Margin="0,12,0,0"/>
</Grid>
</DataTemplate>
</telerikPrimitives:RadSlideView.ItemTemplate>
Is it not what you want ?

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