Skip to content

Commit

Permalink
Updated ItemsControlRegionAdapter to fix previous-binding and allow i…
Browse files Browse the repository at this point in the history
…tems to be added
  • Loading branch information
DamianSuess committed Aug 4, 2024
1 parent faa1058 commit ad1c4a7
Showing 1 changed file with 23 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Avalonia.Controls;
using Prism.Properties;

Expand All @@ -10,18 +11,14 @@ namespace Prism.Navigation.Regions
/// </summary>
public class ItemsControlRegionAdapter : RegionAdapterBase<ItemsControl>
{
/// <summary>
/// Initializes a new instance of <see cref="ItemsControlRegionAdapter"/>.
/// </summary>
/// <summary>Initializes a new instance of <see cref="ItemsControlRegionAdapter"/>.</summary>
/// <param name="regionBehaviorFactory">The factory used to create the region behaviors to attach to the created regions.</param>
public ItemsControlRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory)
: base(regionBehaviorFactory)
{
}

/// <summary>
/// Adapts an <see cref="ItemsControl"/> to an <see cref="IRegion"/>.
/// </summary>
/// <summary>Adapts an <see cref="ItemsControl"/> to an <see cref="IRegion"/>.</summary>
/// <param name="region">The new region being used.</param>
/// <param name="regionTarget">The object to adapt.</param>
protected override void Adapt(IRegion region, ItemsControl regionTarget)
Expand All @@ -33,30 +30,46 @@ protected override void Adapt(IRegion region, ItemsControl regionTarget)
throw new ArgumentNullException(nameof(regionTarget));

// NOTE: In Avalonia, Items will never be null
// Removed: Avalonia v11.1.1
// Prism.Wpf throws, but we keep it rollin' baby!
/*
bool itemsSourceIsSet = regionTarget.ItemCount > 0;
itemsSourceIsSet = itemsSourceIsSet || regionTarget.HasBinding(ItemsControl.ItemsSourceProperty);
if (itemsSourceIsSet)
{
throw new InvalidOperationException(Resources.ItemsControlHasItemsSourceException);
}
*/

// If control has child items, move them to the region and then bind control to region. Can't set ItemsSource if child items exist.
if (regionTarget.ItemCount > 0)
{
foreach (object childItem in regionTarget.Items)
{
region.Add(childItem);
}

// Control must be empty before setting ItemsSource
regionTarget.Items.Clear();
}

// Detect when an item has been added/removed to the ItemsControl's backing region. Copy
// all items to a new collection and bind to the region's ItemsSource
region.Views.CollectionChanged += (s, e) =>
{
var enumerator = region.Views.GetEnumerator();
List<object> items = new();
while (enumerator.MoveNext())
{
items.Add(enumerator.Current);
}
regionTarget.ItemsSource = items;
};

// Avalonia v11-Preview5 needs IRegion implement IList. Enforcing it to return AvaloniaList<object> fixes this.
// Avalonia v11-Preview8 ItemsControl.Items is readonly (#10827).
////regionTarget.Items = region.Views as Avalonia.Collections.AvaloniaList<object>;
regionTarget.ItemsSource = region.Views as Avalonia.Collections.AvaloniaList<object>;
// Removed: Avalonia v11.1.1
////regionTarget.ItemsSource = region.Views as Avalonia.Collections.AvaloniaList<object>;
}

/// <summary>
Expand Down

0 comments on commit ad1c4a7

Please sign in to comment.