зеркало из https://github.com/DeGsoft/maui-linux.git
[iOS] If the UITableView hasn't rendered anything yet don't try to sync cells (#3090) fixes #1342 fixes #1542 fixes #1927
* [iOS] fixes #1342 - verify the UITableView has rendered cells before trying to synchronize to collection * - let reset through on CollectionChanged
This commit is contained in:
Родитель
781165fabd
Коммит
d6810346d1
|
@ -0,0 +1,170 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Text;
|
||||
using System.Windows.Input;
|
||||
using Xamarin.Forms.CustomAttributes;
|
||||
using Xamarin.Forms.Internals;
|
||||
|
||||
|
||||
#if UITEST
|
||||
using Xamarin.UITest;
|
||||
using NUnit.Framework;
|
||||
using Xamarin.Forms.Core.UITests;
|
||||
#endif
|
||||
|
||||
namespace Xamarin.Forms.Controls.Issues
|
||||
{
|
||||
[Preserve(AllMembers = true)]
|
||||
[Issue(IssueTracker.Github, 1342, "[iOS] ListView throws Exception on ObservableCollection.Add/Remove for non visible list view",
|
||||
PlatformAffected.iOS)]
|
||||
#if UITEST
|
||||
[NUnit.Framework.Category(UITestCategories.ListView)]
|
||||
#endif
|
||||
public class Issue1342 : TestNavigationPage
|
||||
{
|
||||
const string add2 = "add2";
|
||||
const string add3 = "add3";
|
||||
const string success = "No crash means success";
|
||||
|
||||
protected override void Init()
|
||||
{
|
||||
PushAsync(new MainPageCode
|
||||
{
|
||||
BindingContext = new MainViewModel
|
||||
{
|
||||
ViewModel1 = new ListViewModel
|
||||
{
|
||||
Items = new ObservableCollection<string>(new[] { $"Click {add2}", $"Click {add3}", success })
|
||||
},
|
||||
ViewModel2 = new ListViewModel
|
||||
{
|
||||
Items = new ObservableCollection<string>(new[] { "item2.1", "item2.2", "item2.3" })
|
||||
},
|
||||
ViewModel3 = new ListViewModel
|
||||
{
|
||||
Items = new ObservableCollection<string>()
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Preserve(AllMembers = true)]
|
||||
public partial class MainPageCode : TabbedPage
|
||||
{
|
||||
public MainPageCode()
|
||||
{
|
||||
ToolbarItems.Add(new Xamarin.Forms.ToolbarItem() { Text = "add1" });
|
||||
ToolbarItems.Add(new Xamarin.Forms.ToolbarItem() { Text = $"{add2}" });
|
||||
ToolbarItems.Add(new Xamarin.Forms.ToolbarItem() { Text = $"{add3}" });
|
||||
ToolbarItems.Add(new Xamarin.Forms.ToolbarItem() { Text = "reload" });
|
||||
ToolbarItems.Add(new Xamarin.Forms.ToolbarItem() { Text = "visible" });
|
||||
|
||||
|
||||
ToolbarItems[0].SetBinding(ToolbarItem.CommandProperty, "Add1Command");
|
||||
ToolbarItems[1].SetBinding(ToolbarItem.CommandProperty, "Add2Command");
|
||||
ToolbarItems[2].SetBinding(ToolbarItem.CommandProperty, "Add3Command");
|
||||
ToolbarItems[3].SetBinding(ToolbarItem.CommandProperty, "Add4Command");
|
||||
ToolbarItems[4].SetBinding(ToolbarItem.CommandProperty, "Add5Command");
|
||||
|
||||
ListPageCode page = new ListPageCode();
|
||||
page.SetBinding(ListPageCode.BindingContextProperty, "ViewModel1");
|
||||
Children.Add(page);
|
||||
|
||||
page = new ListPageCode();
|
||||
page.SetBinding(ListPageCode.BindingContextProperty, "ViewModel2");
|
||||
Children.Add(page);
|
||||
|
||||
page = new ListPageCode();
|
||||
page.SetBinding(ListPageCode.BindingContextProperty, "ViewModel3");
|
||||
Children.Add(page);
|
||||
}
|
||||
}
|
||||
|
||||
[Preserve(AllMembers = true)]
|
||||
public class MainViewModel
|
||||
{
|
||||
|
||||
void AddItems(ObservableCollection<string> list)
|
||||
{
|
||||
list.Add("new item");
|
||||
}
|
||||
|
||||
public MainViewModel()
|
||||
{
|
||||
Add1Command = new Command(() => AddItems(ViewModel1.Items));
|
||||
Add2Command = new Command(() => AddItems(ViewModel2.Items));
|
||||
Add3Command = new Command(() => AddItems(ViewModel3.Items));
|
||||
Add4Command = new Command(() =>
|
||||
{
|
||||
ViewModel1.ReloadData();
|
||||
ViewModel2.ReloadData();
|
||||
ViewModel3.ReloadData();
|
||||
});
|
||||
Add5Command = new Command(() =>
|
||||
{
|
||||
ViewModel1.ChangeListViewVisability();
|
||||
ViewModel2.ChangeListViewVisability();
|
||||
ViewModel3.ReloadData();
|
||||
});
|
||||
}
|
||||
|
||||
public ListViewModel ViewModel1 { get; set; }
|
||||
public ListViewModel ViewModel2 { get; set; }
|
||||
public ListViewModel ViewModel3 { get; set; }
|
||||
|
||||
public ICommand Add1Command { get; }
|
||||
public ICommand Add2Command { get; }
|
||||
public ICommand Add3Command { get; }
|
||||
public ICommand Add4Command { get; }
|
||||
public ICommand Add5Command { get; }
|
||||
}
|
||||
|
||||
[Preserve(AllMembers = true)]
|
||||
public class ListViewModel : INotifyPropertyChanged
|
||||
{
|
||||
public ObservableCollection<string> Items { get; set; }
|
||||
public bool IsVisible { get; set; } = true;
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public void ReloadData()
|
||||
{
|
||||
Items = new ObservableCollection<string>();
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Items)));
|
||||
}
|
||||
|
||||
public void ChangeListViewVisability()
|
||||
{
|
||||
IsVisible = !IsVisible;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsVisible)));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[Preserve(AllMembers = true)]
|
||||
public partial class ListPageCode : ContentPage
|
||||
{
|
||||
public ListPageCode()
|
||||
{
|
||||
Icon = "coffee.png";
|
||||
ListView view = new ListView(ListViewCachingStrategy.RecycleElement);
|
||||
Content = view;
|
||||
|
||||
view.SetBinding(ListView.ItemsSourceProperty, "Items");
|
||||
view.SetBinding(ListView.IsVisibleProperty, "IsVisible");
|
||||
}
|
||||
}
|
||||
|
||||
#if UITEST
|
||||
[Test]
|
||||
public void AddingItemsToNonVisibleListViewDoesntCrash()
|
||||
{
|
||||
RunningApp.Tap(add2);
|
||||
RunningApp.Tap(add3);
|
||||
RunningApp.WaitForElement(success);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -244,6 +244,7 @@
|
|||
<Compile Include="$(MSBuildThisFileDirectory)Issue1799.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue1931.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue3089.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue1342.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue2767.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Issue2499.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)GitHub1878.cs" />
|
||||
|
|
|
@ -530,6 +530,11 @@ namespace Xamarin.Forms.Platform.iOS
|
|||
if (exArgs != null)
|
||||
_dataSource.Counts[section] = exArgs.Count;
|
||||
|
||||
// This means the UITableView hasn't rendered any cells yet
|
||||
// so there's no need to synchronize the rows on the UITableView
|
||||
if (Control.IndexPathsForVisibleRows == null && e.Action != NotifyCollectionChangedAction.Reset)
|
||||
return;
|
||||
|
||||
var groupReset = resetWhenGrouped && Element.IsGroupingEnabled;
|
||||
|
||||
// We can't do this check on grouped lists because the index doesn't match the number of rows in a section.
|
||||
|
|
Загрузка…
Ссылка в новой задаче