From 8064ce21468ba2bc68576f1cb5589b7620ef64f6 Mon Sep 17 00:00:00 2001 From: Curtis Wensley Date: Tue, 25 Oct 2022 15:11:42 -0700 Subject: [PATCH] Mac: GridView.DataSource fixes - When setting DataSource to null it would not reload the row count - Avoid crashes when GridView row count gets out of sync --- src/Eto.Mac/Forms/Controls/GridViewHandler.cs | 48 +++++++++++++------ src/Eto/CollectionChangedHandler.cs | 4 +- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/Eto.Mac/Forms/Controls/GridViewHandler.cs b/src/Eto.Mac/Forms/Controls/GridViewHandler.cs index bb8c468f0d..2f010fc9a9 100644 --- a/src/Eto.Mac/Forms/Controls/GridViewHandler.cs +++ b/src/Eto.Mac/Forms/Controls/GridViewHandler.cs @@ -164,32 +164,44 @@ public class EtoTableViewDataSource : NSTableViewDataSource { WeakReference handler; - public GridViewHandler Handler { get { return (GridViewHandler)(handler != null ? handler.Target : null); } set { handler = new WeakReference(value); } } + public GridViewHandler Handler { get => (GridViewHandler)handler?.Target; set => handler = new WeakReference(value); } - public override nint GetRowCount(NSTableView tableView) - { - return (Handler.collection != null && Handler.collection.Collection != null) ? Handler.collection.Count : 0; - } + public override nint GetRowCount(NSTableView tableView) => Handler?.collection?.Count ?? 0; public override NSObject GetObjectValue(NSTableView tableView, NSTableColumn tableColumn, nint row) { - var item = Handler.collection.ElementAt((int)row); - var colHandler = Handler.GetColumn(tableColumn); - return colHandler == null ? null : colHandler.GetObjectValue(item); + var h = Handler; + if (h == null) + return null; + + if (row >= h.collection.Count) + { + // re-jig as we're off somehow.. usually because of some programming error, but let's be nice and not actually crash. + tableView.ReloadData(); + return null; + } + var colHandler = h.GetColumn(tableColumn); + var item = h.collection.ElementAt((int)row); + return colHandler?.GetObjectValue(item); } public override void SetObjectValue(NSTableView tableView, NSObject theObject, NSTableColumn tableColumn, nint row) { - if (row >= Handler.collection.Count) + var h = Handler; + if (h == null) return; - var item = Handler.collection.ElementAt((int)row); - var colHandler = Handler.GetColumn(tableColumn); - if (colHandler != null && Handler.SuppressUpdate == 0) + + if (row >= h.collection.Count) + return; + + var item = h.collection.ElementAt((int)row); + var colHandler = h.GetColumn(tableColumn); + if (colHandler != null && h.SuppressUpdate == 0) { colHandler.SetObjectValue(item, theObject); - Handler.SetIsEditing(false); - Handler.Callback.OnCellEdited(Handler.Widget, new GridViewCellEventArgs(colHandler.Widget, (int)row, colHandler.Column, item)); + h.SetIsEditing(false); + h.Callback.OnCellEdited(h.Widget, new GridViewCellEventArgs(colHandler.Widget, (int)row, colHandler.Column, item)); } } @@ -590,13 +602,19 @@ public override void RemoveAllItems() public IEnumerable DataStore { - get { return collection != null ? collection.Collection : null; } + get => collection?.Collection; set { if (collection != null) + { + if (ReferenceEquals(collection.Collection, value)) + return; collection.Unregister(); + } collection = new CollectionHandler { Handler = this }; collection.Register(value); + Control.ReloadData(); + AutoSizeColumns(true); ResetAutoSizedColumns(); InvalidateMeasure(); } diff --git a/src/Eto/CollectionChangedHandler.cs b/src/Eto/CollectionChangedHandler.cs index baa1e463fb..62ffa39c6d 100644 --- a/src/Eto/CollectionChangedHandler.cs +++ b/src/Eto/CollectionChangedHandler.cs @@ -76,9 +76,9 @@ public virtual void Unregister() { notify.CollectionChanged -= CollectionChanged; } - OnUnregisterCollection(EventArgs.Empty); - Collection = null; + + OnUnregisterCollection(EventArgs.Empty); } ///