From a7733365b6f418af56ccc17f5fd4bb5ac686db3a Mon Sep 17 00:00:00 2001 From: Curtis Wensley Date: Wed, 11 Dec 2024 02:05:06 -0800 Subject: [PATCH] Fix issue mapping view to model in SelectableFilterCollection Fixes #2676 --- src/Eto/Forms/FilterCollection.cs | 11 ++-- .../Controls/GridViewSelectableFilterTests.cs | 54 ++++++++++++++++--- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/Eto/Forms/FilterCollection.cs b/src/Eto/Forms/FilterCollection.cs index cd8638e5db..d6cf272ffd 100644 --- a/src/Eto/Forms/FilterCollection.cs +++ b/src/Eto/Forms/FilterCollection.cs @@ -173,15 +173,20 @@ protected override void Rebuild() viewToModel = new Dictionary(Count); for (int i = 0; i < Count; i++) { + // used for lookup below, this index is not correct yet viewToModel.Add(this[i], i); } modelToView = new Dictionary(Count); - for (int i = 0; i < Items.Count; i++) + for (int j = 0; j < Items.Count; j++) { int index; - if (viewToModel.TryGetValue(Items[i], out index)) - modelToView.Add(i, index); + if (viewToModel.TryGetValue(Items[j], out index)) + { + modelToView.Add(j, index); + // update index with real index in model + viewToModel[Items[j]] = j; + } } } else diff --git a/test/Eto.Test/UnitTests/Forms/Controls/GridViewSelectableFilterTests.cs b/test/Eto.Test/UnitTests/Forms/Controls/GridViewSelectableFilterTests.cs index 04a1ae18c2..0513d48919 100644 --- a/test/Eto.Test/UnitTests/Forms/Controls/GridViewSelectableFilterTests.cs +++ b/test/Eto.Test/UnitTests/Forms/Controls/GridViewSelectableFilterTests.cs @@ -8,7 +8,7 @@ namespace Eto.Test.UnitTests.Forms.Controls /// (c) 2014 by Vivek Jhaveri /// See LICENSE for full terms [TestFixture] - public class GridViewSelectableFilterTests + public class GridViewSelectableFilterTests : TestBase { GridView grid; ObservableCollection model; @@ -21,7 +21,7 @@ public class GridViewSelectableFilterTests [SetUp] public void Setup() { - TestBase.Invoke(() => + Invoke(() => { grid = new GridView(); // Some platforms need at least one column for selection to work @@ -40,7 +40,7 @@ public void Setup() [Test] public void InsertItemShouldNotChangeSelection() { - TestBase.Invoke(() => + Invoke(() => { grid.SelectRow(0); var selectedItem = grid.SelectedItem; @@ -52,7 +52,7 @@ public void InsertItemShouldNotChangeSelection() [Test] public void DeleteSelectedItemsShouldRemoveSelectedItems() { - TestBase.Invoke(() => + Invoke(() => { grid.AllowMultipleSelection = true; @@ -88,7 +88,7 @@ public void DeleteSelectedItemsShouldRemoveSelectedItems() [TestCase(2)] public void SortItemsShouldNotChangeSelection(int rowToSelect) { - TestBase.Invoke(() => + Invoke(() => { filtered.Sort = GridViewUtils.SortItemsAscending; grid.SelectRow(rowToSelect); @@ -111,7 +111,7 @@ public void SortItemsShouldNotChangeSelection(int rowToSelect) [Test] public void FilterItemsShouldNotChangeSelection() { - TestBase.Invoke(() => + Invoke(() => { grid.AllowMultipleSelection = true; @@ -137,5 +137,47 @@ public void FilterItemsShouldNotChangeSelection() Assert.AreEqual(0, modelSelectionChangedCount, "Model SelectionChanged event should not fire when changing filter"); }); } + + [Test] + public void SortedCollectionShouldGetCorrectRow() + { + GridView grid = null; + Shown(form => + { + grid = new GridView { Size = new Size(200, 200) }; + var collection = new SelectableFilterCollection(grid) + { + new("Hello"), + new("There"), + new("Fine"), + new("World"), + new("Of"), + new("Eto") + }; + + grid.Columns.Add(new GridColumn + { + DataCell = new TextBoxCell(0) + }); + grid.DataStore = collection; + collection.Sort = (x, y) => string.Compare((string)x.Values[0], (string)y.Values[0], StringComparison.Ordinal); + // goes to this order: + // Eto + // Fine + // Hello + // Of + // There + // World + + collection.SelectRow(4); + form.Content = grid; + }, () => { + + Assert.AreEqual(3, grid.SelectedRow, "#1"); + Assert.NotNull(grid.SelectedItem, "#2"); + Assert.AreEqual("Of", ((GridItem)grid.SelectedItem).Values[0], "#3"); + }); + } + } } \ No newline at end of file