File: System\Windows\Forms\Dialogs\TaskDialog\TaskDialogButtonCollection.cs
Web Access
Project: src\src\System.Windows.Forms\src\System.Windows.Forms.csproj (System.Windows.Forms)
// 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);
    }
}