| File: System\ComponentModel\Design\CollectionEditor.CollectionForm.cs | Web Access |
| Project: src\winforms\src\System.Windows.Forms.Design\src\System.Windows.Forms.Design.csproj (System.Windows.Forms.Design) |
// 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; using System.Windows.Forms; using System.Windows.Forms.Design; namespace System.ComponentModel.Design; public partial class CollectionEditor { /// <summary> /// The <see cref="CollectionForm"/> provides a modal dialog for editing the contents of a collection. /// </summary> protected abstract class CollectionForm : Form { private readonly CollectionEditor _editor; private object? _value; private short _editableState = EditableDynamic; private const short EditableDynamic = 0; private const short EditableYes = 1; private const short EditableNo = 2; /// <summary> /// Initializes a new instance of the <see cref="CollectionForm"/> class. /// </summary> public CollectionForm(CollectionEditor editor) { _editor = editor.OrThrowIfNull(); } /// <summary> /// Gets or sets the data type of each item in the collection. /// </summary> protected Type CollectionItemType => _editor.CollectionItemType; /// <summary> /// Gets or sets the type of the collection. /// </summary> protected Type CollectionType => _editor.CollectionType; internal virtual bool CollectionEditable { get { if (_editableState != EditableDynamic) { return _editableState == EditableYes; } bool editable = typeof(IList).IsAssignableFrom(_editor.CollectionType); if (editable) { if (EditValue is IList list) { return !list.IsReadOnly; } } return editable; } set => _editableState = value ? EditableYes : EditableNo; } /// <summary> /// Gets or sets a type descriptor that indicates the current context. /// </summary> protected ITypeDescriptorContext? Context => _editor.Context; /// <summary> /// Gets or sets the value of the item being edited. /// </summary> public object? EditValue { get => _value; set { _value = value; OnEditValueChanged(); } } /// <summary> /// Gets or sets the array of items this form is to display. /// </summary> [AllowNull] protected object[] Items { get => _editor.GetItems(EditValue); set { // Request our desire to make a change. bool canChange = false; try { if (Context is not null) { canChange = Context.OnComponentChanging(); } } catch (Exception ex) when (!ex.IsCriticalException()) { DisplayError(ex); } if (canChange) { object? newValue = _editor.SetItems(EditValue, value); if (newValue != EditValue) { EditValue = newValue; } Context!.OnComponentChanged(); } } } /// <summary> /// Gets or sets the available item types that can be created for this collection. /// </summary> protected Type[] NewItemTypes => _editor.NewItemTypes; /// <summary> /// Gets or sets a value indicating whether original members of the collection can be removed. /// </summary> protected bool CanRemoveInstance(object value) => _editor.CanRemoveInstance(value); /// <summary> /// Gets or sets a value indicating whether multiple collection members can be selected. /// </summary> protected virtual bool CanSelectMultipleInstances() => _editor.CanSelectMultipleInstances(); /// <summary> /// Creates a new instance of the specified collection item type. /// </summary> protected object CreateInstance(Type itemType) => _editor.CreateInstance(itemType); /// <summary> /// Destroys the specified instance of the object. /// </summary> protected void DestroyInstance(object instance) => _editor.DestroyInstance(instance); /// <summary> /// Displays the given exception to the user. /// </summary> protected virtual void DisplayError(Exception e) { if (GetService(typeof(IUIService)) is IUIService uis) { uis.ShowError(e); } else { string message = e.Message; if (string.IsNullOrEmpty(message)) { message = e.ToString(); } RTLAwareMessageBox.Show( owner: null, message, caption: null, MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1, 0); } } /// <summary> /// Gets the requested service, if it is available. /// </summary> protected override object? GetService(Type serviceType) => _editor.GetService(serviceType); /// <summary> /// Called to show the dialog via the IWindowsFormsEditorService /// </summary> protected internal virtual DialogResult ShowEditorDialog(IWindowsFormsEditorService edSvc) { ArgumentNullException.ThrowIfNull(edSvc); return edSvc.ShowDialog(this); } /// <summary> /// This is called when the value property in the <see cref="CollectionForm"/> has changed. /// </summary> protected abstract void OnEditValueChanged(); } }