2021-09-07 12:10:58 +02:00
|
|
|
using System;
|
2018-06-29 19:52:40 +02:00
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Collections.ObjectModel;
|
|
|
|
|
using System.Collections.Specialized;
|
|
|
|
|
using System.Runtime.Serialization;
|
2021-09-07 12:10:58 +02:00
|
|
|
using Umbraco.Extensions;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2021-02-18 11:06:02 +01:00
|
|
|
namespace Umbraco.Cms.Core.Models
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Represents a collection of <see cref="PropertyGroup"/> objects
|
|
|
|
|
/// </summary>
|
|
|
|
|
[Serializable]
|
|
|
|
|
[DataContract]
|
2019-01-27 01:17:32 -05:00
|
|
|
// TODO: Change this to ObservableDictionary so we can reduce the INotifyCollectionChanged implementation details
|
2018-06-29 19:52:40 +02:00
|
|
|
public class PropertyGroupCollection : KeyedCollection<string, PropertyGroup>, INotifyCollectionChanged, IDeepCloneable
|
|
|
|
|
{
|
2021-07-01 11:35:05 +02:00
|
|
|
/// <summary>
|
2021-07-13 14:49:57 +02:00
|
|
|
/// Initializes a new instance of the <see cref="PropertyGroupCollection" /> class.
|
2021-07-01 11:35:05 +02:00
|
|
|
/// </summary>
|
2019-11-18 13:03:24 +01:00
|
|
|
public PropertyGroupCollection()
|
2018-06-29 19:52:40 +02:00
|
|
|
{ }
|
|
|
|
|
|
2021-07-13 14:49:57 +02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="PropertyGroupCollection" /> class.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="groups">The groups.</param>
|
2021-09-07 14:40:45 +02:00
|
|
|
public PropertyGroupCollection(IEnumerable<PropertyGroup> groups) => Reset(groups);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Resets the collection to only contain the <see cref="PropertyGroup"/> instances referenced in the <paramref name="groups"/> parameter.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="groups">The property groups.</param>
|
|
|
|
|
/// <remarks></remarks>
|
|
|
|
|
internal void Reset(IEnumerable<PropertyGroup> groups)
|
|
|
|
|
{
|
2021-08-02 11:35:39 +02:00
|
|
|
// Collection events will be raised in each of these calls
|
2018-06-29 19:52:40 +02:00
|
|
|
Clear();
|
2019-04-16 17:37:42 +10:00
|
|
|
|
2021-07-01 11:35:05 +02:00
|
|
|
// Collection events will be raised in each of these calls
|
2018-06-29 19:52:40 +02:00
|
|
|
foreach (var group in groups)
|
|
|
|
|
Add(group);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void SetItem(int index, PropertyGroup item)
|
|
|
|
|
{
|
2019-04-16 17:37:42 +10:00
|
|
|
var oldItem = index >= 0 ? this[index] : item;
|
2022-02-09 13:24:35 +01:00
|
|
|
|
2018-06-29 19:52:40 +02:00
|
|
|
base.SetItem(index, item);
|
2021-07-13 14:49:57 +02:00
|
|
|
|
2021-08-04 13:11:31 +02:00
|
|
|
oldItem.Collection = null;
|
|
|
|
|
item.Collection = this;
|
2021-07-13 14:49:57 +02:00
|
|
|
|
2019-04-16 17:37:42 +10:00
|
|
|
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, item, oldItem));
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void RemoveItem(int index)
|
|
|
|
|
{
|
|
|
|
|
var removed = this[index];
|
2021-07-13 14:49:57 +02:00
|
|
|
|
2018-06-29 19:52:40 +02:00
|
|
|
base.RemoveItem(index);
|
2021-08-04 13:11:31 +02:00
|
|
|
|
|
|
|
|
removed.Collection = null;
|
|
|
|
|
|
2018-06-29 19:52:40 +02:00
|
|
|
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, removed));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void InsertItem(int index, PropertyGroup item)
|
|
|
|
|
{
|
|
|
|
|
base.InsertItem(index, item);
|
2021-08-04 13:11:31 +02:00
|
|
|
|
|
|
|
|
item.Collection = this;
|
|
|
|
|
|
2018-06-29 19:52:40 +02:00
|
|
|
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void ClearItems()
|
|
|
|
|
{
|
2021-07-13 14:49:57 +02:00
|
|
|
foreach (var item in this)
|
|
|
|
|
{
|
2021-08-04 13:11:31 +02:00
|
|
|
item.Collection = null;
|
2021-07-13 14:49:57 +02:00
|
|
|
}
|
|
|
|
|
|
2018-06-29 19:52:40 +02:00
|
|
|
base.ClearItems();
|
|
|
|
|
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-18 15:17:18 +01:00
|
|
|
public new void Add(PropertyGroup item)
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2021-08-02 11:35:39 +02:00
|
|
|
// Ensure alias is set
|
|
|
|
|
if (string.IsNullOrEmpty(item.Alias))
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2021-09-07 12:10:58 +02:00
|
|
|
throw new InvalidOperationException("Set an alias before adding the property group.");
|
2021-08-02 11:35:39 +02:00
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2021-08-02 11:35:39 +02:00
|
|
|
// Note this is done to ensure existing groups can be renamed
|
2021-04-20 16:09:52 +10:00
|
|
|
if (item.HasIdentity && item.Id > 0)
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2021-08-02 11:35:39 +02:00
|
|
|
var index = IndexOfKey(item.Id);
|
|
|
|
|
if (index != -1)
|
2021-04-20 16:09:52 +10:00
|
|
|
{
|
2021-08-02 11:35:39 +02:00
|
|
|
var keyExists = Contains(item.Alias);
|
2021-04-20 16:09:52 +10:00
|
|
|
if (keyExists)
|
2021-08-02 11:35:39 +02:00
|
|
|
throw new ArgumentException($"Naming conflict: changing the alias of property group '{item.Name}' would result in duplicates.");
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2021-08-02 11:35:39 +02:00
|
|
|
// Collection events will be raised in SetItem
|
|
|
|
|
SetItem(index, item);
|
2021-04-20 16:09:52 +10:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2021-08-02 11:35:39 +02:00
|
|
|
var index = IndexOfKey(item.Alias);
|
|
|
|
|
if (index != -1)
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2021-08-02 11:35:39 +02:00
|
|
|
// Collection events will be raised in SetItem
|
|
|
|
|
SetItem(index, item);
|
|
|
|
|
return;
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
}
|
2021-08-02 11:35:39 +02:00
|
|
|
|
|
|
|
|
// Collection events will be raised in InsertItem
|
2021-04-20 16:09:52 +10:00
|
|
|
base.Add(item);
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
|
2021-09-07 14:40:45 +02:00
|
|
|
internal void ChangeKey(PropertyGroup item, string newKey) => ChangeItemKey(item, newKey);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2021-09-07 14:40:45 +02:00
|
|
|
public bool Contains(int id) => this.IndexOfKey(id) != -1;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2021-09-07 12:10:58 +02:00
|
|
|
public int IndexOfKey(string key) => this.FindIndex(x => x.Alias == key);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2021-07-01 11:35:05 +02:00
|
|
|
public int IndexOfKey(int id) => this.FindIndex(x => x.Id == id);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2021-07-13 14:49:57 +02:00
|
|
|
protected override string GetKeyForItem(PropertyGroup item) => item.Alias;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2022-02-09 13:24:35 +01:00
|
|
|
public event NotifyCollectionChangedEventHandler? CollectionChanged;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2021-01-12 13:41:50 +11:00
|
|
|
/// <summary>
|
|
|
|
|
/// Clears all <see cref="CollectionChanged"/> event handlers
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void ClearCollectionChangedEvents() => CollectionChanged = null;
|
|
|
|
|
|
2021-09-07 14:40:45 +02:00
|
|
|
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs args) => CollectionChanged?.Invoke(this, args);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
|
|
|
|
public object DeepClone()
|
|
|
|
|
{
|
|
|
|
|
var clone = new PropertyGroupCollection();
|
|
|
|
|
foreach (var group in this)
|
|
|
|
|
{
|
2018-10-17 18:09:52 +11:00
|
|
|
clone.Add((PropertyGroup)group.DeepClone());
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
2021-07-01 11:35:05 +02:00
|
|
|
|
2018-06-29 19:52:40 +02:00
|
|
|
return clone;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|