diff --git a/Toolkit.Foundation/ObservableCollection.cs b/Toolkit.Foundation/ObservableCollection.cs index b691142..cb6011c 100644 --- a/Toolkit.Foundation/ObservableCollection.cs +++ b/Toolkit.Foundation/ObservableCollection.cs @@ -127,7 +127,7 @@ public partial class ObservableCollection : object? IList.this[int index] { - get => index >= 0 ? collection[index] : null; + get => index >= 0 && collection.Count > 0 ? collection[index] : null; set { TItem? item = default; @@ -144,6 +144,59 @@ public partial class ObservableCollection : } } + public void SetSource(IList source) + { + foreach (TItem item in source) + { + Add(item); + } + + if (source is INotifyCollectionChanged observableSource) + { + observableSource.CollectionChanged += SourceCollectionChanged; + } + } + + private void SourceCollectionChanged(object? sender, + NotifyCollectionChangedEventArgs args) + { + switch (args.Action) + { + case NotifyCollectionChangedAction.Add: + if (args.NewItems is not null) + { + foreach (TItem newItem in args.NewItems) + { + Add(newItem); + } + } + break; + case NotifyCollectionChangedAction.Remove: + if (args.OldItems is not null) + { + foreach (TItem oldItem in args.OldItems) + { + if (this.FirstOrDefault(x => x.Equals(oldItem)) is TItem removedItem) + { + Remove(removedItem); + } + } + } + break; + case NotifyCollectionChangedAction.Reset: + + Clear(); + if (sender is IEnumerable collection) + { + foreach (TItem item in collection) + { + Add(item); + } + } + break; + } + } + public virtual Task OnActivated() { IsActivated = true; @@ -210,16 +263,33 @@ public partial class ObservableCollection : } } - public void Clear(Action> factory) + public void Reset(Action> factory, bool disposeItems = true) { - Clear(); + Clear(disposeItems); factory.Invoke(this); } + public void Clear(bool disposeItems = false) + { + isClearing = true; + + if (disposeItems) + { + foreach (TItem item in this.ToList()) + { + Disposer.Dispose(item); + Disposer.Remove(this, item); + } + + } + + ClearItems(); + isClearing = false; + } + public void Clear() { isClearing = true; - foreach (TItem item in this.ToList()) { Disposer.Dispose(item); diff --git a/Toolkit.UI.Avalonia/InvokeNavigationViewItemAction.cs b/Toolkit.UI.Avalonia/InvokeNavigationViewItemAction.cs index 8e40daf..97464e9 100644 --- a/Toolkit.UI.Avalonia/InvokeNavigationViewItemAction.cs +++ b/Toolkit.UI.Avalonia/InvokeNavigationViewItemAction.cs @@ -1,5 +1,4 @@ using Avalonia; -using Avalonia.Controls; using Avalonia.Threading; using Avalonia.Xaml.Interactivity; using System.Collections; diff --git a/Toolkit.UI.Controls.Avalonia/NavigationView/NavigationView.cs b/Toolkit.UI.Controls.Avalonia/NavigationView/NavigationView.cs index 369fee4..3baa982 100644 --- a/Toolkit.UI.Controls.Avalonia/NavigationView/NavigationView.cs +++ b/Toolkit.UI.Controls.Avalonia/NavigationView/NavigationView.cs @@ -1,8 +1,39 @@ -namespace Toolkit.UI.Controls.Avalonia; +using FluentAvalonia.UI.Controls; +using System.Reflection; + +namespace Toolkit.UI.Controls.Avalonia; public class NavigationView : FluentAvalonia.UI.Controls.NavigationView { + public NavigationView() + { + ItemInvoked += OnItemInvoked; + } + protected override Type StyleKeyOverride => typeof(FluentAvalonia.UI.Controls.NavigationView); + + private void ApplyNavigationFix() + { + if (typeof(FluentAvalonia.UI.Controls.NavigationView) + .GetField("_shouldRaiseItemInvokedAfterSelection", + BindingFlags.NonPublic | BindingFlags.Instance) + is FieldInfo shouldRaiseItemInvokedAfterSelectionFieldInfo) + { + if (shouldRaiseItemInvokedAfterSelectionFieldInfo.GetValue(this) is bool value) + { + if (value) + { + shouldRaiseItemInvokedAfterSelectionFieldInfo.SetValue(this, false); + } + } + }; + } + + private void OnItemInvoked(object? sender, + NavigationViewItemInvokedEventArgs args) + { + ApplyNavigationFix(); + } } \ No newline at end of file