Files
Umbraco-CMS/src/Umbraco.Core/Models/PropertyGroupCollection.cs

157 lines
5.3 KiB
C#
Raw Normal View History

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;
using Umbraco.Extensions;
2018-06-29 19:52:40 +02: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]
// 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
{
/// <summary>
/// Initializes a new instance of the <see cref="PropertyGroupCollection" /> class.
/// </summary>
public PropertyGroupCollection()
2018-06-29 19:52:40 +02:00
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PropertyGroupCollection" /> class.
/// </summary>
/// <param name="groups">The groups.</param>
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)
{
// Collection events will be raised in each of these calls
2018-06-29 19:52:40 +02:00
Clear();
// 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)
{
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);
oldItem.Collection = null;
item.Collection = this;
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];
2018-06-29 19:52:40 +02:00
base.RemoveItem(index);
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);
item.Collection = this;
2018-06-29 19:52:40 +02:00
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
}
protected override void ClearItems()
{
foreach (var item in this)
{
item.Collection = null;
}
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
{
// Ensure alias is set
if (string.IsNullOrEmpty(item.Alias))
2018-06-29 19:52:40 +02:00
{
throw new InvalidOperationException("Set an alias before adding the property group.");
}
2018-06-29 19:52:40 +02:00
// Note this is done to ensure existing groups can be renamed
if (item.HasIdentity && item.Id > 0)
2018-06-29 19:52:40 +02:00
{
var index = IndexOfKey(item.Id);
if (index != -1)
{
var keyExists = Contains(item.Alias);
if (keyExists)
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
// Collection events will be raised in SetItem
SetItem(index, item);
return;
}
}
else
{
var index = IndexOfKey(item.Alias);
if (index != -1)
2018-06-29 19:52:40 +02:00
{
// Collection events will be raised in SetItem
SetItem(index, item);
return;
2018-06-29 19:52:40 +02:00
}
}
// Collection events will be raised in InsertItem
base.Add(item);
2018-06-29 19:52:40 +02:00
}
internal void ChangeKey(PropertyGroup item, string newKey) => ChangeItemKey(item, newKey);
2018-06-29 19:52:40 +02:00
public bool Contains(int id) => this.IndexOfKey(id) != -1;
2018-06-29 19:52:40 +02:00
public int IndexOfKey(string key) => this.FindIndex(x => x.Alias == key);
2018-06-29 19:52:40 +02:00
public int IndexOfKey(int id) => this.FindIndex(x => x.Id == id);
2018-06-29 19:52:40 +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
/// <summary>
/// Clears all <see cref="CollectionChanged"/> event handlers
/// </summary>
public void ClearCollectionChangedEvents() => CollectionChanged = null;
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)
{
clone.Add((PropertyGroup)group.DeepClone());
2018-06-29 19:52:40 +02:00
}
2018-06-29 19:52:40 +02:00
return clone;
}
}
}