Browse Source

Handle uninitialized Source in SelectedItemsSync.

If the `SelectionModel` passed to `SelectedItemsSync` has not yet had a `Source` assigned, set a flag to write the selected items to the `SelectionModel` when `Source` is set.

Fixes #4272
pull/4440/head
Steven Kirk 6 years ago
parent
commit
0f9ac73b4f
  1. 37
      src/Avalonia.Controls/Utils/SelectedItemsSync.cs

37
src/Avalonia.Controls/Utils/SelectedItemsSync.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq; using System.Linq;
using Avalonia.Collections; using Avalonia.Collections;
@ -16,6 +17,7 @@ namespace Avalonia.Controls.Utils
private IList? _items; private IList? _items;
private bool _updatingItems; private bool _updatingItems;
private bool _updatingModel; private bool _updatingModel;
private bool _initializeOnSourceAssignment;
public SelectedItemsSync(ISelectionModel model) public SelectedItemsSync(ISelectionModel model)
{ {
@ -63,10 +65,18 @@ namespace Avalonia.Controls.Utils
_updatingModel = true; _updatingModel = true;
_items = items; _items = items;
using (Model.Update()) if (Model.Source is object)
{ {
Model.ClearSelection(); using (Model.Update())
Add(items); {
Model.ClearSelection();
Add(items);
}
}
else if (!_initializeOnSourceAssignment)
{
Model.PropertyChanged += SelectionModelPropertyChanged;
_initializeOnSourceAssignment = true;
} }
if (_items is INotifyCollectionChanged incc2) if (_items is INotifyCollectionChanged incc2)
@ -86,9 +96,11 @@ namespace Avalonia.Controls.Utils
if (_items != null) if (_items != null)
{ {
Model.PropertyChanged -= SelectionModelPropertyChanged;
Model.SelectionChanged -= SelectionModelSelectionChanged; Model.SelectionChanged -= SelectionModelSelectionChanged;
Model = model; Model = model;
Model.SelectionChanged += SelectionModelSelectionChanged; Model.SelectionChanged += SelectionModelSelectionChanged;
_initializeOnSourceAssignment = false;
try try
{ {
@ -175,6 +187,25 @@ namespace Avalonia.Controls.Utils
} }
} }
private void SelectionModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (_initializeOnSourceAssignment &&
_items != null &&
e.PropertyName == nameof(SelectionModel.Source))
{
try
{
_updatingModel = true;
Add(_items);
_initializeOnSourceAssignment = false;
}
finally
{
_updatingModel = false;
}
}
}
private void SelectionModelSelectionChanged(object sender, SelectionModelSelectionChangedEventArgs e) private void SelectionModelSelectionChanged(object sender, SelectionModelSelectionChangedEventArgs e)
{ {
if (_updatingModel) if (_updatingModel)

Loading…
Cancel
Save