Bug 22535 - HasUnevenRows don't work in Listview with iOS
Summary: HasUnevenRows don't work in Listview with iOS
Status: RESOLVED INVALID
Alias: None
Product: Forms
Classification: Xamarin
Component: Forms ()
Version: 1.2.3
Hardware: PC Windows
: High normal
Target Milestone: ---
Assignee: Bugzilla
URL:
: 22597 ()
Depends on:
Blocks:
 
Reported: 2014-09-01 07:23 UTC by Fredy Wenger
Modified: 2015-02-12 03:10 UTC (History)
9 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Description with Screenshots (1.35 MB, application/pdf)
2014-09-02 08:28 UTC, Fredy Wenger
Details
Additional description (810.67 KB, application/pdf)
2014-09-12 10:34 UTC, Fredy Wenger
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED INVALID

Description Fredy Wenger 2014-09-01 07:23:08 UTC
Xamarin.Forms, ListView, iOS, HasUnevenRows don't work.

I query data from a webservice.
The result is stored in a list with 1-n entrys from type object.
In the list, there are some textfields and image-fields.

I show the result in a listview.
The length of data in the testfields is variable (some contains more, some less text)
For the image I have set HeightRequest = 200 and WidthRequest = 200, 

As the length in the text-fields is variable, I want to set HasUnevenRows to true to the Listview (so that the needed high is settled automatically at runtime.

Problem description:
HasUnevenRows to the ListView works as expected on Android (HW) and with WP-Emulator.
HasUnevenRows to the ListView don’t work with iOS.
=> On iOS all elements are showed "stacked" on the same space

Code-snipped:

lvErgebnisAnzeige = new ListView
{
   HasUnevenRows = true, // DON’T WORK WITH IOS, works with Android (HW) and WP-Emulator 
//RowHeight = 600, // to display the ListView in iOS, the RowHeight has to set to a value (what in don’t want to do)
};
//
lvErgebnisAnzeige.ItemSelected += (sender, e) =>
{
  var eq = (Empfehlung)e.SelectedItem; 
  string cAnzeige = "Selektiert: " + eq.cAdresse.Trim() + " / Key: " + eq.iAnbieterKey;
  DisplayAlert("Empfehlung info", cAnzeige, "OK");
};

Content = new StackLayout
{
  Padding = new Thickness(0, 20, 0, 0),
  Children = { indicator, lStatusAbfrage, piServerAuswahl, piGuide, btEmpfehlungenLaden, lvErgebnisAnzeige,}
};

// Cellendefinition 
class EmpfehlungenCell : ViewCell
{
  public EmpfehlungenCell()
  {
    var image = new Image
    { HorizontalOptions = LayoutOptions.Start, HeightRequest = 200, WidthRequest = 200, VerticalOptions = LayoutOptions.Start, };


image.SetBinding(Image.SourceProperty, "bAnbieterFoto");
image.BindingContextChanged += (sender, e) =>
{
  base.OnBindingContextChanged();
  var c = BindingContext as Empfehlung; 
  string cFotoBase64 = c.bAnbieterFoto; 
  Byte[] ImageFotoBase64 = System.Convert.FromBase64String(cFotoBase64); 
  image.Source = ImageSource.FromStream(() => new MemoryStream(ImageFotoBase64)); 
};
var EmpfehlungLayout = CreateEmpfehlungenLayout();
// Viewlayout-Grunddefinition
var viewLayout = new StackLayout() { Orientation = StackOrientation.Horizontal, Children = { image, EmpfehlungLayout } };
// Ausrichtung anpassen für Phone / Tablet              
if (Device.Idiom == TargetIdiom.Phone)
{ viewLayout.Orientation = StackOrientation.Vertical; }
else
{ viewLayout.Orientation = StackOrientation.Horizontal; }
  View = viewLayout;
}

static StackLayout CreateEmpfehlungenLayout()
// Labels
var AdressLabel = new Label { HorizontalOptions = LayoutOptions.FillAndExpand};
AdressLabel.SetBinding(Label.TextProperty, "cAdresse");
//
var SloganLabel = new Label { HorizontalOptions = LayoutOptions.FillAndExpand };
SloganLabel.SetBinding(Label.TextProperty, "cAnbieterSlogan");
//
var AngeboteLabel = new Label { HorizontalOptions = LayoutOptions.FillAndExpand };
AngeboteLabel.SetBinding(Label.TextProperty, "cAngebote");
//
var TitelAngeboteLabel = new Label { Text = "Angebote:", HorizontalOptions = LayoutOptions.FillAndExpand, Font = Font.SystemFontOfSize(14, FontAttributes.Bold ),};
//
var nameLayout = new StackLayout()
{
  HorizontalOptions = LayoutOptions.StartAndExpand,
  Orientation = StackOrientation.Vertical,
  Children = { AdressLabel, SloganLabel, TitelAngeboteLabel, AngeboteLabel }
};
  return nameLayout;
}
Comment 1 Arpit Jha 2014-09-02 04:32:53 UTC
I have checked this issue but unable to reproduce it.

I have tried following steps.
1.Create a Xamarin forms Application.
2.Add a class UnevenRowsCell.cs and did Some code.
3.Add a class UnevenRowsPage.cs and Did Some Code.
4. Set 	listView.HasUnevenRows = true;
4.Call UnevenRowsPage.cs in App.cs
5. Set .ios project as Start tup project
6.Run the application.

I observed that  listView.HasUnevenRows property is working fine.

//  UnevenRowsCell.cs class

public class UnevenRowsCell : ViewCell
	{
		public UnevenRowsCell ()
		{
			var label1 = new Label { Text = "Label 1", Font = Font.SystemFontOfSize(NamedSize.Small) };
			label1.SetBinding(Label.TextProperty, new Binding("."));

			View = new StackLayout {
				Orientation = StackOrientation.Vertical,
				VerticalOptions = LayoutOptions.StartAndExpand,
				Padding = new Thickness (15, 5, 5, 5),
				Children = { label1 }
			};
		}


		const int avgCharsInRow = 35;
		const int defaultHeight = 44;
		const int extraLineHeight = 20;
		protected override void OnBindingContextChanged ()
		{
			base.OnBindingContextChanged ();

			if (Device.OS == TargetPlatform.iOS) {
				var text = (string)BindingContext;

				var len = text.Length;

				if (len < (avgCharsInRow * 2)) {
					// fits in one cell
					Height = defaultHeight;
				} else {
					len = len - (avgCharsInRow * 2);
					var extraRows = len / 35;
					Height = defaultHeight + extraRows * extraLineHeight;
				}
			}
		}
	}

// UnevenRowsPage.cs

public class UnevenRowsPage : ContentPage
	{
		public UnevenRowsPage ()
		{
			var listView = new ListView ();

			listView.HasUnevenRows = true;

			// http://en.wikipedia.org/wiki/To_be,_or_not_to_be
			listView.ItemsSource = new [] { 
				"To be, or not to be,", 
				"that is the question— Whether 'tis Nobler in the mind to suffer",
				@"The Slings and Arrows of outrageous Fortune,
Or to take Arms against a Sea of troubles,",
				@"And by opposing end them? To die, to sleep—
No more; and by a sleep, to say we end
The Heart-ache, and the thousand Natural shocks",
				@"That Flesh is heir to? 'Tis a consummation
Devoutly to be wished. To die, to sleep,
To sleep, perchance to Dream; Aye, there's the rub,
For in that sleep of death, what dreams may come,",
				@"When we have shuffled off this mortal coil,
Must give us pause. "
			
			};
			listView.ItemTemplate = new DataTemplate(typeof(UnevenRowsCell));

			listView.ItemTapped += (sender, e) => {
				if (e == null) return; // has been set to null, do not 'process' tapped event
				Debug.WriteLine("Tapped: " + e.Item);
				((ListView)sender).SelectedItem = null; // de-select the row
			};

			Padding = new Thickness (0,20,0,0);
			Content = listView;
		}
	}


//App.cs
public class App
	{
		/// <summary>
		/// This sample includes both C# and XAML versions of the user interface.
		/// UNCOMMENT the version below that you wish to try
		/// </summary>
		public static Page GetMainPage ()
		{

			
            return new UnevenRowsPage();
          
		}
	}

Let me know if i have to follow other steps to reproduce it.
Screencast:  
http://screencast.com/t/tEncGuWtXUup

http://screencast.com/t/C4Bn6yctW8t

http://screencast.com/t/mQHlw5EFo

Environment Info:
VS 2013 Update 3
XVS 3.3.47.0
Xamarin.forms 
1.2.2.6243
Comment 2 Fredy Wenger 2014-09-02 08:27:20 UTC
Hi Arpit

Thanks for Feedback

As this bug is elementar (it is a "killer"), I have created a documentation for you with screenshots. I also upload the .cs file with the page for you (sorry.. as I am in testing, there are much commented lines).

If (really) needed, I also can submit you my whole project (if you handle it confidential).
With the whole project you also should ne able to query data from our webservice.

Let me know, if you need the whole project. 

Please give this problem a high priority, as it is a real "killer".
If the Height cannot is not calculates correct automatically, it's simple not usable for iOS (it's not clever and smart to set a fix height).

Thanks
Fredy
Comment 3 Fredy Wenger 2014-09-02 08:28:42 UTC
Created attachment 7883 [details]
Description with Screenshots

Description with Screenshots
-> See my last posting
Comment 5 Arpit Jha 2014-09-02 11:31:41 UTC
I have checked this issue and Now able to reproduce it.

I have tried following steps to reproduce it.
1.Create  Xamarin form application.
2.Add a class(.cs) and did some code in it.
3.Call .cs class in App.cs
4.Set ios as startup project.
5.Run the application.

I observed that content of listview overlaps but when we set row height then Listview looks as expected.

I can reproduce the reported behavior HasUnevenRows don't work in Listview with iOS . I’ll need confirmation from the developer if this is a bug. Leaving as NEW for now.


public  class MyPage : ContentPage
    {
        ListView lvErgebnisAnzeige;
        Label lStatusAbfrage;


     public MyPage()
     {          
            
            lvErgebnisAnzeige = new ListView
            {   
                HasUnevenRows = true,               
            };
        
            lvErgebnisAnzeige.ItemsSource = new[] { 
				"To be, or not to be,", 
				"that is the question— Whether 'tis Nobler in the mind to suffer",
				@"The Slings and Arrows of outrageous Fortune,
Or to take Arms against a Sea of troubles,",
				@"And by opposing end them? To die, to sleep—
No more; and by a sleep, to say we end
The Heart-ache, and the thousand Natural shocks",
				@"That Flesh is heir to? 'Tis a consummation
Devoutly to be wished. To die, to sleep,
To sleep, perchance to Dream; Aye, there's the rub,
For in that sleep of death, what dreams may come,",
				@"When we have shuffled off this mortal coil,
Must give us pause. "
			
			};
            lvErgebnisAnzeige.ItemTemplate = new DataTemplate(typeof(UnevenRowsCell));         
            lvErgebnisAnzeige.ItemSelected += (sender, e) =>
            {
                //var eq = (Empfehlung)e.SelectedItem; // aktuell selektiertes Objekt übernehmen -> als Parameter auf die Detailseite übergeben
                //string cAnzeige = "Selektiert: " + eq.cAdresse.Trim() + " / Key: " + eq.iAnbieterKey;
                //DisplayAlert("Empfehlung info", cAnzeige, "OK");
                //this.Navigation.PushAsync(new SucheDetails(eq)); // Detailseite mit Objekt aufrufenh
            };         
            Content = new StackLayout
            {
                Padding = new Thickness(0, 20, 0, 0),
                Children = { 
                    
 					lvErgebnisAnzeige,
                   				}
            };
     
     }
    }
Screencast: http://screencast.com/t/Q3yOvMjad

Environment Info:
VS 2013 Update 3
XVS 3.3.47.0
Xamarin.forms 
1.2.2.6243
Comment 6 Fredy Wenger 2014-09-02 11:53:30 UTC
Hi Arpit

Thanks for confirm the bug.

Please help, that the bug will be fixed soon, as it blocks development for iOS.

Greetings from Switzerland.
Fredy
Comment 7 Fredy Wenger 2014-09-03 11:23:40 UTC
See also (new) bug:

https://bugzilla.xamarin.com/show_bug.cgi?id=22597

I think the bugs are related...
Comment 8 Sadik Ali 2014-09-05 00:41:24 UTC
*** Bug 22597 has been marked as a duplicate of this bug. ***
Comment 9 Fredy Wenger 2014-09-12 10:34:16 UTC
Created attachment 8032 [details]
Additional description

See las message
Comment 10 Fredy Wenger 2014-09-12 10:39:07 UTC
Sadik:
You have marked my second bug-entry as duplicate and ALSO HAVE DELETED MY 
ADDITIONAL SECOND description specially to the text-cut-bug.

I have added the attachment once again to this bug.

Can you (or somebody else) give me a Feedback, until when the bug will be fixed as this is a show stopper for me)?

Thanks
Fredy
Comment 11 Eric Maupin 2014-09-12 17:16:39 UTC
iOS does not support automatically sizing row cells, you must set a ListView.RowHeight or a Cell.Height. Unfortunately, we did not specifically disable this from working on Android or Windows Phone (where it just works without our intervention), and it has lead some to believe that iOS is broken in this respect.

Unfortunately this is a limitation of the iOS platform and therefore is the intended behavior.
Comment 12 Fredy Wenger 2014-09-15 03:50:26 UTC
Sorry, but I can't accept that.
There is a special property (hasunevenrows), that works as expected in Android and WP.
It can't be, that this don't work in iOS.
My Input ist dynamic and bindet - so I have no idea how to calculate it myself and I don't want to calculate it myself. 
.Forms is specially for multiplatform (write once, run on ALL platforms.
So... I expect, that XAMARIN implements something, that this also works with iOS, otherwise the property (hasunvenerows) don't work  and can't be used!

Fredy
Comment 13 Sergio Paganoni 2014-11-13 10:36:32 UTC
Actually I'm on the same boat, how are we suppose to compute the height of the row for iOS based only on the text length?

What would be the solution to not have stacked content? (except setting the row height to a "big" number) Can you provide an example of this?

I think Fredy has made a good point, either the feature is supported by all three platform or shouldn't be included in Xamarin.Forms at all...

Greetings from Switzerland too ;)
Comment 14 Daniel Halan 2015-01-31 10:47:47 UTC
I agree that the calculation should be inside Xamarin framework. But until it gets implemented it should throw a NotSupportedException when the HasUnevenRows property is set on iOS, otherwise this will definitely be regarded as a bug.
Comment 15 John Miller [MSFT] 2015-02-02 08:19:45 UTC
There is documentation on what can be used for all platforms, including what is required for iOS here: http://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/listview/#unevenrows
Comment 16 Fredy Wenger 2015-02-02 08:22:43 UTC
@John Miller:  
This Link is well known (old) - BUT NO SOLUTION (not usable in the real world).
Comment 17 Alexey Kinev 2015-02-12 03:10:08 UTC
@Fredy Wenger:
Yes! In real world it's necessary to measure strings size exactly. I don't know if there's a cleaner way, but I found one that works. I just use native calls to get string size for specified font name and size: https://gist.github.com/rudyryk/7b9633e847e727d12de7

That's really not perfect, but works for me :)