From 932659169e4606111547e8440b6cd0eb56ad46b0 Mon Sep 17 00:00:00 2001 From: Lee Richardson Date: Fri, 12 Apr 2024 21:17:09 +0100 Subject: [PATCH 1/8] Fix a couple of selection related bugs in the grid view If you switched to Multi mode, unselected everything, and switched back to Single then you could no longer select anything. I reproduced this in raw GtkSharp but I can't find the cause so this is a workaround. If you switched to Multi and back to Single you could no longer unselect anything. This was due to AllowMultipleSelection starting in Single but setting Browse. --- src/Eto.Gtk/Forms/Controls/GridHandler.cs | 15 ++++++++- .../Forms/Controls/GridViewSelectTests.cs | 31 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/Eto.Gtk/Forms/Controls/GridHandler.cs b/src/Eto.Gtk/Forms/Controls/GridHandler.cs index 669ad7660a..d2765ea83d 100644 --- a/src/Eto.Gtk/Forms/Controls/GridHandler.cs +++ b/src/Eto.Gtk/Forms/Controls/GridHandler.cs @@ -534,7 +534,20 @@ public void ColumnClicked(GridColumnHandler column) public bool AllowMultipleSelection { get { return Control.Selection.Mode == Gtk.SelectionMode.Multiple; } - set { Control.Selection.Mode = value ? Gtk.SelectionMode.Multiple : Gtk.SelectionMode.Browse; } + set + { + if (value) + { + Control.Selection.Mode = Gtk.SelectionMode.Multiple; + } + else + { + Control.GetCursor(out var cursorRow, out _); + Control.Selection.Mode = Gtk.SelectionMode.None; + Control.Selection.Mode = Gtk.SelectionMode.Single; + Control.Selection.SelectPath(cursorRow); + } + } } public virtual IEnumerable SelectedRows diff --git a/test/Eto.Test/UnitTests/Forms/Controls/GridViewSelectTests.cs b/test/Eto.Test/UnitTests/Forms/Controls/GridViewSelectTests.cs index 8dca07d1db..274dd20a4a 100644 --- a/test/Eto.Test/UnitTests/Forms/Controls/GridViewSelectTests.cs +++ b/test/Eto.Test/UnitTests/Forms/Controls/GridViewSelectTests.cs @@ -124,5 +124,36 @@ public void DeleteSelectedItemsShouldRemoveSelectedItems() Assert.AreEqual(initialCount / 4, selectionChangedCount, "SelectionChanged event should fire for each selected item removed"); }); } + + [Test] + public void UnselectingInMultipleModeThenSwitchingToSingleModeShouldNotBreakSelection() + { + TestBase.Shown(form => + { + form.Content = grid; + }, () => + { + grid.AllowEmptySelection = true; + grid.AllowMultipleSelection = true; + grid.UnselectAll(); + grid.AllowMultipleSelection = false; + grid.SelectRow(1); + Assert.AreEqual(1, grid.SelectedRow); + }); + } + + [Test] + public void SwitchingToSingleModeDoesNotBreakUnselecting() + { + TestBase.Invoke(() => + { + grid.AllowEmptySelection = true; + grid.AllowMultipleSelection = true; + grid.SelectRow(1); + grid.AllowMultipleSelection = false; + grid.UnselectAll(); + Assert.AreEqual(-1, grid.SelectedRow); + }); + } } } \ No newline at end of file From 428b8f4cf2d296865a3127e980656d6dcbdc5a55 Mon Sep 17 00:00:00 2001 From: Lee Richardson Date: Fri, 12 Apr 2024 21:17:43 +0100 Subject: [PATCH 2/8] Fix inability to select bottom row of GridView --- src/Eto.Gtk/Forms/Controls/GridHandler.cs | 27 +++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/Eto.Gtk/Forms/Controls/GridHandler.cs b/src/Eto.Gtk/Forms/Controls/GridHandler.cs index d2765ea83d..0c20c6db61 100644 --- a/src/Eto.Gtk/Forms/Controls/GridHandler.cs +++ b/src/Eto.Gtk/Forms/Controls/GridHandler.cs @@ -719,11 +719,34 @@ public bool AllowEmptySelection set => Widget.Properties.TrySet(GridHandler.AllowEmptySelection_Key, value, true); } +#if !GTK2 + private int GetHeaderHeight() + { + if (!ShowHeader) + { + return 0; + } + + int headerHeight = 0; + foreach (var col in Control.Columns) + { + var boundsHeight = col.Button?.GetWindow()?.GetBounds().Height ?? 0; + headerHeight = Math.Max(headerHeight, boundsHeight); + } + + return headerHeight; + } +#endif + private void Widget_MouseDown(object sender, MouseEventArgs e) { if (!e.Handled && e.Buttons == MouseButtons.Primary) { var location = e.Location; +#if !GTK2 + location.Y -= GetHeaderHeight(); +#endif + if (AllowEmptySelection) { // clicked on an empty area @@ -736,12 +759,12 @@ private void Widget_MouseDown(object sender, MouseEventArgs e) else { // cancel ctrl+clicking to remove last selected item - if (Control.GetPathAtPos((int)location.X, (int)location.Y, out var path, out _)) + if (e.Modifiers == Keys.Control && Control.GetPathAtPos((int)location.X, (int)location.Y, out var path, out _)) { if (Control.Model.GetIter(out var iter, path)) { var isSelected = Control.Selection.IterIsSelected(iter); - if (e.Modifiers == Keys.Control && isSelected && Control.Selection.CountSelectedRows() == 1) + if (isSelected && Control.Selection.CountSelectedRows() == 1) { e.Handled = true; } From 27135cd724baed3a499a7c51dc6b20d466bc846f Mon Sep 17 00:00:00 2001 From: Lee Richardson Date: Sat, 13 Apr 2024 12:52:04 +0100 Subject: [PATCH 3/8] WIP selection consistency --- src/Eto.Gtk/Forms/Controls/GridHandler.cs | 86 +++++++++++++++++++++-- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/src/Eto.Gtk/Forms/Controls/GridHandler.cs b/src/Eto.Gtk/Forms/Controls/GridHandler.cs index 0c20c6db61..a4c66a68c4 100644 --- a/src/Eto.Gtk/Forms/Controls/GridHandler.cs +++ b/src/Eto.Gtk/Forms/Controls/GridHandler.cs @@ -1,5 +1,9 @@ using Eto.GtkSharp.Forms.Cells; using Eto.GtkSharp.Forms.Menu; +using Gtk; +using Grid = Eto.Forms.Grid; +using GridLines = Eto.Forms.GridLines; + namespace Eto.GtkSharp.Forms.Controls { class GridHandler @@ -89,6 +93,26 @@ protected GridHandler() // ScrolledWindow.Add(Box); } + /*protected override TreeView CreateControl() + { + var control = base.CreateControl(); + control.Selection.SelectFunction = SelectFunction; + return control; + }*/ + + + private bool SelectFunction(Gtk.TreeSelection selection, Gtk.ITreeModel model, Gtk.TreePath path, bool pathCurrentlySelected) + { + // Cancel removing last selected item + var rows = selection.GetSelectedRows().Select(r => r.Indices[0]); + if (!AllowEmptySelection && AllowMultipleSelection && pathCurrentlySelected && selection.CountSelectedRows() == 1) + { + return false; + } + + return true; + } + protected abstract ITreeModelImplementor CreateModelImplementor(); protected void UpdateModel() @@ -138,12 +162,23 @@ protected override void Initialize() columns.Register(Widget.Columns); base.Initialize(); - Widget.MouseDown += Widget_MouseDown; + //Widget.MouseDown += Widget_MouseDown; Control.QueryTooltip += Control_QueryTooltip; Control.HasTooltip = true; - + //Control.Selection.SelectFunction = SelectFunction; + Control.Selection.Changed += (sender, args) => + { + //if (!AllowEmptySelection && AllowMultipleSelection) + { + if (!AllowEmptySelection && Control.Selection.CountSelectedRows() == 0) + { + Control.GetCursor(out var cursorRow, out _); + Control.Selection.SelectPath(cursorRow); + } + } + }; } private void Control_QueryTooltip(object o, Gtk.QueryTooltipArgs args) @@ -536,17 +571,20 @@ public bool AllowMultipleSelection get { return Control.Selection.Mode == Gtk.SelectionMode.Multiple; } set { - if (value) + SetSelectionMode(AllowEmptySelection, value); + /*if (value) { Control.Selection.Mode = Gtk.SelectionMode.Multiple; } else { + // Workaround to not lose the ability to select after switching to Multi then back to Single. Control.GetCursor(out var cursorRow, out _); Control.Selection.Mode = Gtk.SelectionMode.None; Control.Selection.Mode = Gtk.SelectionMode.Single; Control.Selection.SelectPath(cursorRow); } + SetSelectionMode();*/ } } @@ -716,7 +754,47 @@ public bool IsEditing public bool AllowEmptySelection { get => Widget.Properties.Get(GridHandler.AllowEmptySelection_Key, true); - set => Widget.Properties.TrySet(GridHandler.AllowEmptySelection_Key, value, true); + set + { + Widget.Properties.TrySet(GridHandler.AllowEmptySelection_Key, value, true); + SetSelectionMode(value, AllowMultipleSelection); + } + } + + private void SetSelectionMode(bool allowEmptySelection, bool allowMultipleSelection) + { + var currentMode = Control.Selection.Mode; + var newMode = + (allowEmptySelection, allowMultipleSelection) switch + { + (true, true) => SelectionMode.Multiple, + (true, false) => SelectionMode.Single, + (false, true) => SelectionMode.Multiple, // Handled by SelectFunction + (false, false) => SelectionMode.Browse + }; + + if (newMode != currentMode) + { + if (currentMode == SelectionMode.Multiple && newMode != SelectionMode.Multiple) + { + // Workaround to not lose the ability to select after switching to Multi then back to Single or Browse. + Control.Selection.Mode = Gtk.SelectionMode.None; + Control.Selection.Mode = newMode; + //if (Control.Selection.CountSelectedRows() == 0) + { + Control.GetCursor(out var cursorRow, out _); + Control.Selection.SelectPath(cursorRow); + } + } + Control.Selection.Mode = newMode; + } + if (!allowEmptySelection && Control.Selection.CountSelectedRows() == 0) + { + Control.GetCursor(out var cursorRow, out _); + Control.Selection.SelectPath(cursorRow); + } + + //EnsureSelection(); } #if !GTK2 From 8072ff231b6a33bfd732ea98c746a72a6bb10878 Mon Sep 17 00:00:00 2001 From: Lee Richardson Date: Mon, 15 Apr 2024 11:09:57 +0100 Subject: [PATCH 4/8] WIP selection consistency --- src/Eto.Gtk/Forms/Controls/GridHandler.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Eto.Gtk/Forms/Controls/GridHandler.cs b/src/Eto.Gtk/Forms/Controls/GridHandler.cs index a4c66a68c4..80c0fd0c99 100644 --- a/src/Eto.Gtk/Forms/Controls/GridHandler.cs +++ b/src/Eto.Gtk/Forms/Controls/GridHandler.cs @@ -168,7 +168,7 @@ protected override void Initialize() Control.HasTooltip = true; //Control.Selection.SelectFunction = SelectFunction; - Control.Selection.Changed += (sender, args) => + /*Control.Selection.Changed += (sender, args) => { //if (!AllowEmptySelection && AllowMultipleSelection) { @@ -178,7 +178,7 @@ protected override void Initialize() Control.Selection.SelectPath(cursorRow); } } - }; + };*/ } private void Control_QueryTooltip(object o, Gtk.QueryTooltipArgs args) @@ -778,21 +778,26 @@ private void SetSelectionMode(bool allowEmptySelection, bool allowMultipleSelect if (currentMode == SelectionMode.Multiple && newMode != SelectionMode.Multiple) { // Workaround to not lose the ability to select after switching to Multi then back to Single or Browse. + //var firstSelectedRow = Control.Selection.GetSelectedRows().FirstOrDefault();//Control.Selection.CountSelectedRows() > 0 ? Control.Selection.GetSelectedRows()[0] : null; + var anyWereSelected = Control.Selection.CountSelectedRows() > 0; + Control.Selection.Mode = Gtk.SelectionMode.None; Control.Selection.Mode = newMode; - //if (Control.Selection.CountSelectedRows() == 0) + if (anyWereSelected) { + //SkipSelectedChange = true; Control.GetCursor(out var cursorRow, out _); Control.Selection.SelectPath(cursorRow); + //SkipSelectedChange = false; } } Control.Selection.Mode = newMode; } - if (!allowEmptySelection && Control.Selection.CountSelectedRows() == 0) + /*if (!allowEmptySelection && Control.Selection.CountSelectedRows() == 0) { Control.GetCursor(out var cursorRow, out _); Control.Selection.SelectPath(cursorRow); - } + }*/ //EnsureSelection(); } From dd06536f061d07d7f040485d26dd8a2cd705e660 Mon Sep 17 00:00:00 2001 From: Lee Richardson Date: Mon, 15 Apr 2024 11:54:05 +0100 Subject: [PATCH 5/8] Clean up TreeView selection consistency --- src/Eto.Gtk/Forms/Controls/GridHandler.cs | 142 +++------------------- 1 file changed, 17 insertions(+), 125 deletions(-) diff --git a/src/Eto.Gtk/Forms/Controls/GridHandler.cs b/src/Eto.Gtk/Forms/Controls/GridHandler.cs index 80c0fd0c99..1cb336585f 100644 --- a/src/Eto.Gtk/Forms/Controls/GridHandler.cs +++ b/src/Eto.Gtk/Forms/Controls/GridHandler.cs @@ -1,8 +1,5 @@ using Eto.GtkSharp.Forms.Cells; using Eto.GtkSharp.Forms.Menu; -using Gtk; -using Grid = Eto.Forms.Grid; -using GridLines = Eto.Forms.GridLines; namespace Eto.GtkSharp.Forms.Controls { @@ -93,26 +90,6 @@ protected GridHandler() // ScrolledWindow.Add(Box); } - /*protected override TreeView CreateControl() - { - var control = base.CreateControl(); - control.Selection.SelectFunction = SelectFunction; - return control; - }*/ - - - private bool SelectFunction(Gtk.TreeSelection selection, Gtk.ITreeModel model, Gtk.TreePath path, bool pathCurrentlySelected) - { - // Cancel removing last selected item - var rows = selection.GetSelectedRows().Select(r => r.Indices[0]); - if (!AllowEmptySelection && AllowMultipleSelection && pathCurrentlySelected && selection.CountSelectedRows() == 1) - { - return false; - } - - return true; - } - protected abstract ITreeModelImplementor CreateModelImplementor(); protected void UpdateModel() @@ -162,23 +139,18 @@ protected override void Initialize() columns.Register(Widget.Columns); base.Initialize(); - //Widget.MouseDown += Widget_MouseDown; - - Control.QueryTooltip += Control_QueryTooltip; - Control.HasTooltip = true; - - //Control.Selection.SelectFunction = SelectFunction; - /*Control.Selection.Changed += (sender, args) => + Control.Selection.Changed += (sender, args) => { - //if (!AllowEmptySelection && AllowMultipleSelection) + // Prevent unselecting last selected item. + if (!AllowEmptySelection && AllowMultipleSelection && Control.Selection.CountSelectedRows() == 0) { - if (!AllowEmptySelection && Control.Selection.CountSelectedRows() == 0) - { - Control.GetCursor(out var cursorRow, out _); - Control.Selection.SelectPath(cursorRow); - } + Control.GetCursor(out var cursorRow, out _); + Control.Selection.SelectPath(cursorRow); } - };*/ + }; + + Control.QueryTooltip += Control_QueryTooltip; + Control.HasTooltip = true; } private void Control_QueryTooltip(object o, Gtk.QueryTooltipArgs args) @@ -569,23 +541,7 @@ public void ColumnClicked(GridColumnHandler column) public bool AllowMultipleSelection { get { return Control.Selection.Mode == Gtk.SelectionMode.Multiple; } - set - { - SetSelectionMode(AllowEmptySelection, value); - /*if (value) - { - Control.Selection.Mode = Gtk.SelectionMode.Multiple; - } - else - { - // Workaround to not lose the ability to select after switching to Multi then back to Single. - Control.GetCursor(out var cursorRow, out _); - Control.Selection.Mode = Gtk.SelectionMode.None; - Control.Selection.Mode = Gtk.SelectionMode.Single; - Control.Selection.SelectPath(cursorRow); - } - SetSelectionMode();*/ - } + set => SetSelectionMode(AllowEmptySelection, value); } public virtual IEnumerable SelectedRows @@ -767,94 +723,30 @@ private void SetSelectionMode(bool allowEmptySelection, bool allowMultipleSelect var newMode = (allowEmptySelection, allowMultipleSelection) switch { - (true, true) => SelectionMode.Multiple, - (true, false) => SelectionMode.Single, - (false, true) => SelectionMode.Multiple, // Handled by SelectFunction - (false, false) => SelectionMode.Browse + (true, true) => Gtk.SelectionMode.Multiple, + (true, false) => Gtk.SelectionMode.Single, + (false, true) => Gtk.SelectionMode.Multiple, // Handled by SelectFunction + (false, false) => Gtk.SelectionMode.Browse }; if (newMode != currentMode) { - if (currentMode == SelectionMode.Multiple && newMode != SelectionMode.Multiple) + // Workaround to not lose the ability to select after switching to Multi, unselecting everything, + // then switching back to Single or Browse. Cause unknown but reproduced in GtkSharp. + if (currentMode == Gtk.SelectionMode.Multiple && newMode != Gtk.SelectionMode.Multiple) { - // Workaround to not lose the ability to select after switching to Multi then back to Single or Browse. - //var firstSelectedRow = Control.Selection.GetSelectedRows().FirstOrDefault();//Control.Selection.CountSelectedRows() > 0 ? Control.Selection.GetSelectedRows()[0] : null; var anyWereSelected = Control.Selection.CountSelectedRows() > 0; Control.Selection.Mode = Gtk.SelectionMode.None; Control.Selection.Mode = newMode; if (anyWereSelected) { - //SkipSelectedChange = true; Control.GetCursor(out var cursorRow, out _); Control.Selection.SelectPath(cursorRow); - //SkipSelectedChange = false; } } Control.Selection.Mode = newMode; } - /*if (!allowEmptySelection && Control.Selection.CountSelectedRows() == 0) - { - Control.GetCursor(out var cursorRow, out _); - Control.Selection.SelectPath(cursorRow); - }*/ - - //EnsureSelection(); - } - -#if !GTK2 - private int GetHeaderHeight() - { - if (!ShowHeader) - { - return 0; - } - - int headerHeight = 0; - foreach (var col in Control.Columns) - { - var boundsHeight = col.Button?.GetWindow()?.GetBounds().Height ?? 0; - headerHeight = Math.Max(headerHeight, boundsHeight); - } - - return headerHeight; - } -#endif - - private void Widget_MouseDown(object sender, MouseEventArgs e) - { - if (!e.Handled && e.Buttons == MouseButtons.Primary) - { - var location = e.Location; -#if !GTK2 - location.Y -= GetHeaderHeight(); -#endif - - if (AllowEmptySelection) - { - // clicked on an empty area - if (!Control.GetPathAtPos((int)location.X, (int)location.Y, out _, out _)) - { - UnselectAll(); - e.Handled = true; - } - } - else - { - // cancel ctrl+clicking to remove last selected item - if (e.Modifiers == Keys.Control && Control.GetPathAtPos((int)location.X, (int)location.Y, out var path, out _)) - { - if (Control.Model.GetIter(out var iter, path)) - { - var isSelected = Control.Selection.IterIsSelected(iter); - if (isSelected && Control.Selection.CountSelectedRows() == 1) - { - e.Handled = true; - } - } - } - } - } } protected void EnsureSelection() From 7953a2de24e1c6b020f34d84c82146401129e94b Mon Sep 17 00:00:00 2001 From: Lee Richardson Date: Mon, 15 Apr 2024 13:09:21 +0100 Subject: [PATCH 6/8] Match GtkSharp behaviour for switching to Single from Multi If the cursor is on an unselected row then select nothing. --- src/Eto.Gtk/Forms/Controls/GridHandler.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Eto.Gtk/Forms/Controls/GridHandler.cs b/src/Eto.Gtk/Forms/Controls/GridHandler.cs index 1cb336585f..868235f6b9 100644 --- a/src/Eto.Gtk/Forms/Controls/GridHandler.cs +++ b/src/Eto.Gtk/Forms/Controls/GridHandler.cs @@ -725,7 +725,7 @@ private void SetSelectionMode(bool allowEmptySelection, bool allowMultipleSelect { (true, true) => Gtk.SelectionMode.Multiple, (true, false) => Gtk.SelectionMode.Single, - (false, true) => Gtk.SelectionMode.Multiple, // Handled by SelectFunction + (false, true) => Gtk.SelectionMode.Multiple, // Handled by Selection Changed event in Initialize(). (false, false) => Gtk.SelectionMode.Browse }; @@ -733,16 +733,17 @@ private void SetSelectionMode(bool allowEmptySelection, bool allowMultipleSelect { // Workaround to not lose the ability to select after switching to Multi, unselecting everything, // then switching back to Single or Browse. Cause unknown but reproduced in GtkSharp. - if (currentMode == Gtk.SelectionMode.Multiple && newMode != Gtk.SelectionMode.Multiple) + if (currentMode == Gtk.SelectionMode.Multiple + && newMode is Gtk.SelectionMode.Single or Gtk.SelectionMode.Browse) { - var anyWereSelected = Control.Selection.CountSelectedRows() > 0; + Control.GetCursor(out var cursorRowPath, out _); + var cursorWasSelected = Control.Selection.PathIsSelected(cursorRowPath); Control.Selection.Mode = Gtk.SelectionMode.None; Control.Selection.Mode = newMode; - if (anyWereSelected) + if (cursorWasSelected) { - Control.GetCursor(out var cursorRow, out _); - Control.Selection.SelectPath(cursorRow); + Control.Selection.SelectPath(cursorRowPath); } } Control.Selection.Mode = newMode; From 545356964d377e8bd75281f21131cc44221b16e0 Mon Sep 17 00:00:00 2001 From: Lee Richardson Date: Mon, 15 Apr 2024 15:59:21 +0100 Subject: [PATCH 7/8] Don't duplicate setting selection mode --- src/Eto.Gtk/Forms/Controls/GridHandler.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Eto.Gtk/Forms/Controls/GridHandler.cs b/src/Eto.Gtk/Forms/Controls/GridHandler.cs index 868235f6b9..ee828ce49f 100644 --- a/src/Eto.Gtk/Forms/Controls/GridHandler.cs +++ b/src/Eto.Gtk/Forms/Controls/GridHandler.cs @@ -746,7 +746,10 @@ private void SetSelectionMode(bool allowEmptySelection, bool allowMultipleSelect Control.Selection.SelectPath(cursorRowPath); } } - Control.Selection.Mode = newMode; + else + { + Control.Selection.Mode = newMode; + } } } From 8ddba71d512e5f1be1019613d2b5bc1cb34bef52 Mon Sep 17 00:00:00 2001 From: Lee Richardson Date: Mon, 15 Apr 2024 17:17:05 +0100 Subject: [PATCH 8/8] Handle some nulls --- src/Eto.Gtk/Forms/Controls/GridHandler.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Eto.Gtk/Forms/Controls/GridHandler.cs b/src/Eto.Gtk/Forms/Controls/GridHandler.cs index ee828ce49f..5389bbcfd0 100644 --- a/src/Eto.Gtk/Forms/Controls/GridHandler.cs +++ b/src/Eto.Gtk/Forms/Controls/GridHandler.cs @@ -145,7 +145,10 @@ protected override void Initialize() if (!AllowEmptySelection && AllowMultipleSelection && Control.Selection.CountSelectedRows() == 0) { Control.GetCursor(out var cursorRow, out _); - Control.Selection.SelectPath(cursorRow); + if (cursorRow != null) + { + Control.Selection.SelectPath(cursorRow); + } } }; @@ -737,11 +740,12 @@ private void SetSelectionMode(bool allowEmptySelection, bool allowMultipleSelect && newMode is Gtk.SelectionMode.Single or Gtk.SelectionMode.Browse) { Control.GetCursor(out var cursorRowPath, out _); - var cursorWasSelected = Control.Selection.PathIsSelected(cursorRowPath); + var mustReselectCursor = cursorRowPath != null && Control.Selection.PathIsSelected(cursorRowPath); Control.Selection.Mode = Gtk.SelectionMode.None; Control.Selection.Mode = newMode; - if (cursorWasSelected) + + if (mustReselectCursor) { Control.Selection.SelectPath(cursorRowPath); }