| File: System\Windows\Forms\Dialogs\TaskDialog\TaskDialogFootnote.cs | Web Access |
| Project: src\winforms\src\System.Windows.Forms\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. namespace System.Windows.Forms; /// <summary> /// Represents the footnote area of a task dialog. /// </summary> public sealed class TaskDialogFootnote : TaskDialogControl { private string? _text; private TaskDialogIcon? _icon; private bool _boundIconIsFromHandle; private bool _updateTextOnInitialization; /// <summary> /// Initializes a new instance of the <see cref="TaskDialogFootnote"/> class. /// </summary> public TaskDialogFootnote() { } /// <summary> /// Initializes a new instance of the <see cref="TaskDialogFootnote"/> class /// using the given <paramref name="text"/>. /// </summary> /// <param name="text">The text to be displayed in the dialog's footnote area.</param> public TaskDialogFootnote(string? text) : this() { _text = text; } public static implicit operator TaskDialogFootnote(string footnoteText) => new(footnoteText); /// <summary> /// Gets or sets the text to be displayed in the dialog's footnote area. /// </summary> /// <value> /// The text to be displayed in the dialog's footnote area. The default value is <see langword="null"/>. /// </value> /// <remarks> /// <para> /// This control will only be shown if this property is not <see langword="null"/> or an empty string. /// </para> /// <para> /// This property can be set while the dialog is shown. /// </para> /// </remarks> /// <exception cref="InvalidOperationException"> /// The property is set on a footnote instance that is currently bound to a task dialog, but it's not visible as its initial /// <see cref="Text"/> property value was <see langword="null"/> or an empty string. /// - or - /// The property is set on a footnote instance that is currently bound to a task dialog, but the dialog /// has just started navigating to a different page. /// </exception> public string? Text { get => _text; set { DenyIfBoundAndNotCreated(); if (BoundPage is not null) { // If we are bound but waiting for initialization (e.g. immediately after // starting a navigation), we buffer the change until we apply the // initialization (when navigation is finished). if (BoundPage.WaitingForInitialization) { _updateTextOnInitialization = true; } else { BoundPage.BoundDialog!.UpdateTextElement( TASKDIALOG_ELEMENTS.TDE_FOOTER, value); } } _text = value; } } /// <summary> /// Gets or sets the footnote icon. /// </summary> /// <remarks> /// <para> /// This property can be set while the dialog is shown (but in that case, it /// cannot be switched between instances created from an /// <see cref="Drawing.Icon"/> (or from a handle pointer) /// and standard icon instances). /// </para> /// </remarks> /// <exception cref="InvalidOperationException"> /// The property is set on a footnote instance that is currently bound to a task dialog, but it's not visible as its initial /// <see cref="Text"/> property value was <see langword="null"/> or an empty string. /// - or - /// The property is set and the task dialog has started navigating to a new page containing this footnote instance, but the /// <see cref="TaskDialogPage.Created"/> event has not been raised yet. /// - or - /// The property is set on a footnote instance that is currently bound to a task dialog, but the dialog /// has just started navigating to a different page. /// </exception> public unsafe TaskDialogIcon? Icon { get => _icon; set { DenyIfBoundAndNotCreated(); // See comment in TaskDialogPage.Icon for why we don't allow to buffer changes // while waiting for the initialization. DenyIfWaitingForInitialization(); if (BoundPage is not null) { (TASKDIALOGCONFIG._Anonymous2_e__Union icon, bool? iconIsFromHandle) = TaskDialogPage.GetFooterIconValue(value); // The native task dialog icon cannot be updated from a handle // type to a non-handle type and vice versa, so we need to throw // in such a case. if (iconIsFromHandle is not null && iconIsFromHandle != _boundIconIsFromHandle) { throw new InvalidOperationException(SR.TaskDialogCannotUpdateIconType); } BoundPage.BoundDialog!.UpdateIconElement( TASKDIALOG_ICON_ELEMENTS.TDIE_ICON_FOOTER, _boundIconIsFromHandle ? icon.hFooterIcon : (IntPtr)(char*)icon.pszFooterIcon); } _icon = value; } } internal override bool IsCreatable => base.IsCreatable && !TaskDialogPage.IsNativeStringNullOrEmpty(_text); /// <summary> /// Returns a string that represents the current <see cref="TaskDialogFootnote"/> control. /// </summary> /// <returns>A string that contains the control text.</returns> public override string ToString() => _text ?? base.ToString() ?? string.Empty; internal TASKDIALOG_FLAGS Bind(TaskDialogPage page, out TASKDIALOGCONFIG._Anonymous2_e__Union icon) { TASKDIALOG_FLAGS result = Bind(page); icon = TaskDialogPage.GetFooterIconValue(_icon).iconUnion; return result; } private protected override TASKDIALOG_FLAGS BindCore() { TASKDIALOG_FLAGS flags = base.BindCore(); _updateTextOnInitialization = false; _boundIconIsFromHandle = TaskDialogPage.GetFooterIconValue(_icon).iconIsFromHandle ?? false; if (_boundIconIsFromHandle) { flags |= TASKDIALOG_FLAGS.TDF_USE_HICON_FOOTER; } return flags; } private protected override void ApplyInitializationCore() { base.ApplyInitializationCore(); if (_updateTextOnInitialization) { Text = _text; _updateTextOnInitialization = false; } } private protected override void UnbindCore() { _boundIconIsFromHandle = false; base.UnbindCore(); } }