|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.ObjectModel;
namespace System.Windows.Forms;
/// <summary>
/// Represents a collection of <see cref="TaskDialogButton"/> objects.
/// </summary>
public class TaskDialogButtonCollection : Collection<TaskDialogButton>
{
// HashSet to detect duplicate items.
private readonly HashSet<TaskDialogButton> _itemSet = [];
/// <summary>
/// Initializes a new instance of the <see cref="TaskDialogButtonCollection"/> class.
/// </summary>
public TaskDialogButtonCollection()
{
}
internal TaskDialogPage? BoundPage { get; set; }
/// <summary>
/// Creates and adds a <see cref="TaskDialogButton"/> to the collection.
/// </summary>
/// <param name="text">The text of the custom button.</param>
/// <param name="enabled">A value indicating whether the button can respond to user interaction.</param>
/// <param name="allowCloseDialog">A value that indicates whether the task dialog should close
/// when this button is clicked.
/// </param>
/// <returns>The created <see cref="TaskDialogButton"/>.</returns>
/// <exception cref="InvalidOperationException">
/// This collection is currently bound to a task dialog.
/// </exception>
public TaskDialogButton Add(string? text, bool enabled = true, bool allowCloseDialog = true)
{
TaskDialogButton button = new(text, enabled, allowCloseDialog);
Add(button);
return button;
}
/// <inheritdoc/>
/// <exception cref="ArgumentNullException">
/// <paramref name="item"/> is <see langword="null"/>.
/// </exception>
/// <exception cref="ArgumentException">
/// <paramref name="item"/> has already been added to the collection.
/// </exception>
/// <exception cref="InvalidOperationException">
/// <paramref name="item"/> is already a part of a different collection.
/// - or -
/// This collection is currently bound to a task dialog.
/// </exception>
protected override void SetItem(int index, TaskDialogButton item)
{
ArgumentNullException.ThrowIfNull(item);
// Disallow collection modification, so that we don't need to copy it
// when binding the TaskDialogPage.
BoundPage?.DenyIfBound();
DenyIfHasOtherCollection(item);
TaskDialogButton oldItem = this[index];
if (oldItem != item)
{
// First, add the new item (which will throw if it is a duplicate entry),
// then remove the old one.
if (!_itemSet.Add(item))
{
throw new ArgumentException(SR.TaskDialogControlAlreadyAddedToCollection);
}
_itemSet.Remove(oldItem);
oldItem.Collection = null;
item.Collection = this;
}
base.SetItem(index, item);
}
/// <inheritdoc/>
/// <exception cref="ArgumentNullException">
/// <paramref name="item"/> is <see langword="null"/>.
/// </exception>
/// <exception cref="ArgumentException">
/// <paramref name="item"/> has already been added to the collection.
/// </exception>
/// <exception cref="InvalidOperationException">
/// <paramref name="item"/> is already a part of a different collection.
/// - or -
/// This collection is currently bound to a task dialog.
/// </exception>
protected override void InsertItem(int index, TaskDialogButton item)
{
ArgumentNullException.ThrowIfNull(item);
// Disallow collection modification, so that we don't need to copy it
// when binding the TaskDialogPage.
BoundPage?.DenyIfBound();
DenyIfHasOtherCollection(item);
if (!_itemSet.Add(item))
{
throw new ArgumentException(SR.TaskDialogControlAlreadyAddedToCollection);
}
item.Collection = this;
base.InsertItem(index, item);
}
/// <inheritdoc/>
/// <exception cref="InvalidOperationException">
/// This collection is currently bound to a task dialog.
/// </exception>
protected override void RemoveItem(int index)
{
// Disallow collection modification, so that we don't need to copy it
// when binding the TaskDialogPage.
BoundPage?.DenyIfBound();
TaskDialogButton oldItem = this[index];
oldItem.Collection = null;
_itemSet.Remove(oldItem);
base.RemoveItem(index);
}
/// <inheritdoc/>
/// <exception cref="InvalidOperationException">
/// This collection is currently bound to a task dialog.
/// </exception>
protected override void ClearItems()
{
// Disallow collection modification, so that we don't need to copy it
// when binding the TaskDialogPage.
BoundPage?.DenyIfBound();
foreach (TaskDialogButton button in this)
{
button.Collection = null;
}
_itemSet.Clear();
base.ClearItems();
}
private void DenyIfHasOtherCollection(TaskDialogButton item)
{
if (item.Collection is not null && item.Collection != this)
throw new InvalidOperationException(SR.TaskDialogControlIsPartOfOtherCollection);
}
}
|