From 302aabee3221edd06721ea3f8643aa62c331296e Mon Sep 17 00:00:00 2001 From: Ian Oswald Date: Thu, 23 May 2024 12:44:03 -0500 Subject: [PATCH 1/4] - added source source binding list change event handling for navigationview menu/footer items. - Fixed menu/footer items not updating with databinding source if items modified post init. --- .../NavigationView.Properties.cs | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs b/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs index 2f714bcfa..8d05c6d62 100644 --- a/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs +++ b/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs @@ -457,6 +457,31 @@ private void OnMenuItems_CollectionChanged(object? sender, NotifyCollectionChang return; } + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (var item in e.NewItems) + MenuItems.Add(item); + break; + case NotifyCollectionChangedAction.Remove: + foreach (var item in e.OldItems) + if (!e.NewItems.Contains(item)) + MenuItems.Remove(item); + break; + case NotifyCollectionChangedAction.Move: + var moveItem = MenuItems[e.OldStartingIndex]; + MenuItems.RemoveAt(e.OldStartingIndex); + MenuItems.Insert(e.NewStartingIndex, moveItem); + break; + case NotifyCollectionChangedAction.Replace: + MenuItems.RemoveAt(e.OldStartingIndex); + MenuItems.Insert(e.OldStartingIndex, e.NewItems[0]); + break; + case NotifyCollectionChangedAction.Reset: + MenuItems.Clear(); + break; + } + UpdateMenuItemsTemplate(e.NewItems); AddItemsToDictionaries(e.NewItems); } @@ -481,6 +506,8 @@ private static void OnMenuItemsSourceChanged(DependencyObject? d, DependencyProp { navigationView.MenuItems.Add(e.NewValue); } + if (e.NewValue is INotifyCollectionChanged oc) + oc.CollectionChanged += navigationView.OnMenuItems_CollectionChanged; } private void OnFooterMenuItems_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) @@ -490,6 +517,31 @@ private void OnFooterMenuItems_CollectionChanged(object? sender, NotifyCollectio return; } + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (var item in e.NewItems) + FooterMenuItems.Add(item); + break; + case NotifyCollectionChangedAction.Remove: + foreach (var item in e.OldItems) + if (!e.NewItems.Contains(item)) + FooterMenuItems.Remove(item); + break; + case NotifyCollectionChangedAction.Move: + var moveItem = FooterMenuItems[e.OldStartingIndex]; + FooterMenuItems.RemoveAt(e.OldStartingIndex); + FooterMenuItems.Insert(e.NewStartingIndex, moveItem); + break; + case NotifyCollectionChangedAction.Replace: + FooterMenuItems.RemoveAt(e.OldStartingIndex); + FooterMenuItems.Insert(e.OldStartingIndex, e.NewItems[0]); + break; + case NotifyCollectionChangedAction.Reset: + FooterMenuItems.Clear(); + break; + } + UpdateMenuItemsTemplate(e.NewItems); AddItemsToDictionaries(e.NewItems); } @@ -517,6 +569,8 @@ DependencyPropertyChangedEventArgs e { navigationView.FooterMenuItems.Add(e.NewValue); } + if (e.NewValue is INotifyCollectionChanged oc) + oc.CollectionChanged += navigationView.OnFooterMenuItems_CollectionChanged; } private static void OnPaneDisplayModeChanged(DependencyObject? d, DependencyPropertyChangedEventArgs e) From 859ced5eb97b48f10a3674d592c7dcef00f637cf Mon Sep 17 00:00:00 2001 From: Ian Oswald Date: Thu, 23 May 2024 13:57:53 -0500 Subject: [PATCH 2/4] Fixed stackoverflow due to recursive call from collection change event when updating from binding source --- .../NavigationView.Properties.cs | 84 +++++++------------ 1 file changed, 32 insertions(+), 52 deletions(-) diff --git a/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs b/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs index 8d05c6d62..64d8eb4c9 100644 --- a/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs +++ b/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs @@ -449,6 +449,36 @@ public Thickness FrameMargin get => (Thickness)GetValue(FrameMarginProperty); set => SetValue(FrameMarginProperty, value); } + private void OnMenuItemsSource_CollectionChanged(object? sender, IList collection, NotifyCollectionChangedEventArgs e) + { + if (!ReferenceEquals(sender, collection)) + { + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (var item in e.NewItems) + collection.Add(item); + break; + case NotifyCollectionChangedAction.Remove: + foreach (var item in e.OldItems) + if (!e.NewItems.Contains(item)) + collection.Remove(item); + break; + case NotifyCollectionChangedAction.Move: + var moveItem = MenuItems[e.OldStartingIndex]; + collection.RemoveAt(e.OldStartingIndex); + collection.Insert(e.NewStartingIndex, moveItem); + break; + case NotifyCollectionChangedAction.Replace: + collection.RemoveAt(e.OldStartingIndex); + collection.Insert(e.OldStartingIndex, e.NewItems[0]); + break; + case NotifyCollectionChangedAction.Reset: + collection.Clear(); + break; + } + } + } private void OnMenuItems_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { @@ -457,31 +487,6 @@ private void OnMenuItems_CollectionChanged(object? sender, NotifyCollectionChang return; } - switch (e.Action) - { - case NotifyCollectionChangedAction.Add: - foreach (var item in e.NewItems) - MenuItems.Add(item); - break; - case NotifyCollectionChangedAction.Remove: - foreach (var item in e.OldItems) - if (!e.NewItems.Contains(item)) - MenuItems.Remove(item); - break; - case NotifyCollectionChangedAction.Move: - var moveItem = MenuItems[e.OldStartingIndex]; - MenuItems.RemoveAt(e.OldStartingIndex); - MenuItems.Insert(e.NewStartingIndex, moveItem); - break; - case NotifyCollectionChangedAction.Replace: - MenuItems.RemoveAt(e.OldStartingIndex); - MenuItems.Insert(e.OldStartingIndex, e.NewItems[0]); - break; - case NotifyCollectionChangedAction.Reset: - MenuItems.Clear(); - break; - } - UpdateMenuItemsTemplate(e.NewItems); AddItemsToDictionaries(e.NewItems); } @@ -507,7 +512,7 @@ private static void OnMenuItemsSourceChanged(DependencyObject? d, DependencyProp navigationView.MenuItems.Add(e.NewValue); } if (e.NewValue is INotifyCollectionChanged oc) - oc.CollectionChanged += navigationView.OnMenuItems_CollectionChanged; + oc.CollectionChanged += (s, e) => navigationView.OnMenuItemsSource_CollectionChanged(oc, navigationView.MenuItems, e); } private void OnFooterMenuItems_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) @@ -517,31 +522,6 @@ private void OnFooterMenuItems_CollectionChanged(object? sender, NotifyCollectio return; } - switch (e.Action) - { - case NotifyCollectionChangedAction.Add: - foreach (var item in e.NewItems) - FooterMenuItems.Add(item); - break; - case NotifyCollectionChangedAction.Remove: - foreach (var item in e.OldItems) - if (!e.NewItems.Contains(item)) - FooterMenuItems.Remove(item); - break; - case NotifyCollectionChangedAction.Move: - var moveItem = FooterMenuItems[e.OldStartingIndex]; - FooterMenuItems.RemoveAt(e.OldStartingIndex); - FooterMenuItems.Insert(e.NewStartingIndex, moveItem); - break; - case NotifyCollectionChangedAction.Replace: - FooterMenuItems.RemoveAt(e.OldStartingIndex); - FooterMenuItems.Insert(e.OldStartingIndex, e.NewItems[0]); - break; - case NotifyCollectionChangedAction.Reset: - FooterMenuItems.Clear(); - break; - } - UpdateMenuItemsTemplate(e.NewItems); AddItemsToDictionaries(e.NewItems); } @@ -570,7 +550,7 @@ DependencyPropertyChangedEventArgs e navigationView.FooterMenuItems.Add(e.NewValue); } if (e.NewValue is INotifyCollectionChanged oc) - oc.CollectionChanged += navigationView.OnFooterMenuItems_CollectionChanged; + oc.CollectionChanged += (s, e) => navigationView.OnMenuItemsSource_CollectionChanged(oc, navigationView.FooterMenuItems, e); } private static void OnPaneDisplayModeChanged(DependencyObject? d, DependencyPropertyChangedEventArgs e) From a260025cd3aea23e73d92367b8f66ce530d03c2f Mon Sep 17 00:00:00 2001 From: pomian <13592821+pomianowski@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:22:51 +0200 Subject: [PATCH 3/4] Update NavigationView.Properties.cs --- .../NavigationView.Properties.cs | 65 ++++++++++++------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs b/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs index 64d8eb4c9..3915ac51d 100644 --- a/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs +++ b/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs @@ -449,34 +449,43 @@ public Thickness FrameMargin get => (Thickness)GetValue(FrameMarginProperty); set => SetValue(FrameMarginProperty, value); } + private void OnMenuItemsSource_CollectionChanged(object? sender, IList collection, NotifyCollectionChangedEventArgs e) { - if (!ReferenceEquals(sender, collection)) + if (ReferenceEquals(sender, collection)) { - switch (e.Action) - { - case NotifyCollectionChangedAction.Add: - foreach (var item in e.NewItems) - collection.Add(item); - break; - case NotifyCollectionChangedAction.Remove: - foreach (var item in e.OldItems) - if (!e.NewItems.Contains(item)) - collection.Remove(item); - break; - case NotifyCollectionChangedAction.Move: - var moveItem = MenuItems[e.OldStartingIndex]; - collection.RemoveAt(e.OldStartingIndex); - collection.Insert(e.NewStartingIndex, moveItem); - break; - case NotifyCollectionChangedAction.Replace: - collection.RemoveAt(e.OldStartingIndex); - collection.Insert(e.OldStartingIndex, e.NewItems[0]); - break; - case NotifyCollectionChangedAction.Reset: - collection.Clear(); - break; - } + return; + } + + switch (e.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (var item in e.NewItems) + { + collection.Add(item); + } + break; + + case NotifyCollectionChangedAction.Remove: + foreach (var item in e.OldItems) + if (!e.NewItems.Contains(item)) + collection.Remove(item); + break; + + case NotifyCollectionChangedAction.Move: + var moveItem = MenuItems[e.OldStartingIndex]; + collection.RemoveAt(e.OldStartingIndex); + collection.Insert(e.NewStartingIndex, moveItem); + break; + + case NotifyCollectionChangedAction.Replace: + collection.RemoveAt(e.OldStartingIndex); + collection.Insert(e.OldStartingIndex, e.NewItems[0]); + break; + + case NotifyCollectionChangedAction.Reset: + collection.Clear(); + break; } } @@ -511,8 +520,11 @@ private static void OnMenuItemsSourceChanged(DependencyObject? d, DependencyProp { navigationView.MenuItems.Add(e.NewValue); } + if (e.NewValue is INotifyCollectionChanged oc) + { oc.CollectionChanged += (s, e) => navigationView.OnMenuItemsSource_CollectionChanged(oc, navigationView.MenuItems, e); + } } private void OnFooterMenuItems_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) @@ -549,8 +561,11 @@ DependencyPropertyChangedEventArgs e { navigationView.FooterMenuItems.Add(e.NewValue); } + if (e.NewValue is INotifyCollectionChanged oc) + { oc.CollectionChanged += (s, e) => navigationView.OnMenuItemsSource_CollectionChanged(oc, navigationView.FooterMenuItems, e); + } } private static void OnPaneDisplayModeChanged(DependencyObject? d, DependencyPropertyChangedEventArgs e) From 4dfcbadebbdce10f1bf3244f7a56e46811b08b41 Mon Sep 17 00:00:00 2001 From: pomian <13592821+pomianowski@users.noreply.github.com> Date: Mon, 10 Jun 2024 15:25:13 +0200 Subject: [PATCH 4/4] Update NavigationView.Properties.cs --- .../Controls/NavigationView/NavigationView.Properties.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs b/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs index 3915ac51d..746899a80 100644 --- a/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs +++ b/src/Wpf.Ui/Controls/NavigationView/NavigationView.Properties.cs @@ -468,8 +468,12 @@ private void OnMenuItemsSource_CollectionChanged(object? sender, IList collectio case NotifyCollectionChangedAction.Remove: foreach (var item in e.OldItems) + { if (!e.NewItems.Contains(item)) + { collection.Remove(item); + } + } break; case NotifyCollectionChangedAction.Move: