/// <summary>
        /// Compares two objects to determine whether they are equal
        /// </summary>
        /// <param name="obj">The object to compare against.</param>
        /// <returns>A <see cref="System.Boolean"/> value.</returns>
        public override bool Equals(object obj)
        {
            DialogControl control = obj as DialogControl;

            if (control != null)
            {
                return(this.Id == control.Id);
            }

            return(false);
        }
        // Called when a control currently in the collection
        // has a property changing - this is
        // basically to screen out property changes that
        // cannot occur while the dialog is showing
        // because the Win32 API has no way for us to
        // propagate the changes until we re-invoke the Win32 call.
        bool IDialogControlHost.IsControlPropertyChangeAllowed(string propertyName, DialogControl control)
        {
            Debug.Assert(control is TaskDialogControl,
                         "Property changing for a control that is not a TaskDialogControl-derived type");
            Debug.Assert(propertyName != "Name",
                         "Name changes at any time are not supported - public API should have blocked this");

            bool canChange = false;

            if (!NativeDialogShowing)
            {
                // Certain properties can't be changed if the dialog is not showing
                // we need a handle created before we can set these...
                switch (propertyName)
                {
                case "Enabled":
                    canChange = false;
                    break;

                default:
                    canChange = true;
                    break;
                }
            }
            else
            {
                // If the dialog is showing, we can only
                // allow some properties to change.
                switch (propertyName)
                {
                // Properties that CAN'T be changed while dialog is showing.
                case "Text":
                case "Default":
                    canChange = false;
                    break;

                // Properties that CAN be changed while dialog is showing.
                case "ShowElevationIcon":
                case "Enabled":
                    canChange = true;
                    break;

                default:
                    Debug.Assert(true, "Unknown property name coming through property changing handler");
                    break;
                }
            }
            return(canChange);
        }
        /// <summary>
        /// Removes the control at the specified index.
        /// </summary>
        /// <param name="index">The location of the control to remove.</param>
        /// <permission cref="System.InvalidOperationException">
        /// The associated dialog is
        /// showing and cannot be modified.</permission>
        protected override void RemoveItem(int index)
        {
            // Notify that we're about to remove a control.
            // Throw if dialog showing.
            if (!hostingDialog.IsCollectionChangeAllowed())
            {
                throw new InvalidOperationException(LocalizedMessages.DialogCollectionModifyShowingDialog);
            }

            DialogControl control = (DialogControl)Items[index];

            // Unparent and remove.
            control.HostingDialog = null;
            base.RemoveItem(index);

            hostingDialog.ApplyCollectionChanged();
        }
        /// <summary>
        /// Called when a control currently in the collection 
        /// has a property changed.
        /// </summary>
        /// <param name="propertyName">The name of the property changed.</param>
        /// <param name="control">The control whose property has changed.</param>
        public virtual void ApplyControlPropertyChange(string propertyName, DialogControl control)
        {
            if (control == null)
            {
                throw new ArgumentNullException("control");
            }

            CommonFileDialogControl dialogControl = null;
            if (propertyName == "Text")
            {
                CommonFileDialogTextBox textBox = control as CommonFileDialogTextBox;

                if (textBox != null)
                {
                    customize.SetEditBoxText(control.Id, textBox.Text);
                }
                else
                {
                    customize.SetControlLabel(control.Id, textBox.Text);
                }
            }
            else if (propertyName == "Visible" && (dialogControl = control as CommonFileDialogControl) != null)
            {
                ShellNativeMethods.ControlState state;
                customize.GetControlState(control.Id, out state);

                if (dialogControl.Visible == true)
                {
                    state |= ShellNativeMethods.ControlState.Visible;
                }
                else if (dialogControl.Visible == false)
                {
                    state &= ~ShellNativeMethods.ControlState.Visible;
                }

                customize.SetControlState(control.Id, state);
            }
            else if (propertyName == "Enabled" && dialogControl != null)
            {
                ShellNativeMethods.ControlState state;
                customize.GetControlState(control.Id, out state);

                if (dialogControl.Enabled == true)
                {
                    state |= ShellNativeMethods.ControlState.Enable;
                }
                else if (dialogControl.Enabled == false)
                {
                    state &= ~ShellNativeMethods.ControlState.Enable;
                }

                customize.SetControlState(control.Id, state);
            }
            else if (propertyName == "SelectedIndex")
            {
                CommonFileDialogRadioButtonList list;
                CommonFileDialogComboBox box;

                if ((list = control as CommonFileDialogRadioButtonList) != null)
                {
                    customize.SetSelectedControlItem(list.Id, list.SelectedIndex);
                }
                else if ((box = control as CommonFileDialogComboBox) != null)
                {
                    customize.SetSelectedControlItem(box.Id, box.SelectedIndex);
                }
            }
            else if (propertyName == "IsChecked")
            {
                CommonFileDialogCheckBox checkBox = control as CommonFileDialogCheckBox;
                if (checkBox != null)
                {
                    customize.SetCheckButtonState(checkBox.Id, checkBox.IsChecked);
                }
            }
        }
 /// <summary>
 /// Determines if changes to a specific property are allowed.
 /// </summary>
 /// <param name="propertyName">The name of the property.</param>
 /// <param name="control">The control propertyName applies to.</param>
 /// <returns>true if the property change is allowed.</returns>
 public virtual bool IsControlPropertyChangeAllowed(string propertyName, DialogControl control)
 {
     CommonFileDialog.GenerateNotImplementedException();
     return false;
 }
        // Called when a control currently in the collection 
        // has a property changed - this handles propagating
        // the new property values to the Win32 API. 
        // If there isn't a way to change the Win32 value, then we
        // should have already screened out the property set 
        // in NotifyControlPropertyChanging.        
        void IDialogControlHost.ApplyControlPropertyChange(string propertyName, DialogControl control)
        {
            // We only need to apply changes to the 
            // native dialog when it actually exists.
            if (NativeDialogShowing)
            {
                TaskDialogButton button;
                TaskDialogRadioButton radioButton;
                if (control is TaskDialogProgressBar)
                {
                    if (!progressBar.HasValidValues)
                    {
                        throw new ArgumentException(LocalizedMessages.TaskDialogProgressBarValueInRange);
                    }

                    switch (propertyName)
                    {
                        case "State":
                            nativeDialog.UpdateProgressBarState(progressBar.State);
                            break;
                        case "Value":
                            nativeDialog.UpdateProgressBarValue(progressBar.Value);
                            break;
                        case "Minimum":
                        case "Maximum":
                            nativeDialog.UpdateProgressBarRange();
                            break;
                        default:
                            Debug.Assert(true, "Unknown property being set");
                            break;
                    }
                }
                else if ((button = control as TaskDialogButton) != null)
                {
                    switch (propertyName)
                    {
                        case "ShowElevationIcon":
                            nativeDialog.UpdateElevationIcon(button.Id, button.UseElevationIcon);
                            break;
                        case "Enabled":
                            nativeDialog.UpdateButtonEnabled(button.Id, button.Enabled);
                            break;
                        default:
                            Debug.Assert(true, "Unknown property being set");
                            break;
                    }
                }
                else if ((radioButton = control as TaskDialogRadioButton) != null)
                {
                    switch (propertyName)
                    {
                        case "Enabled":
                            nativeDialog.UpdateRadioButtonEnabled(radioButton.Id, radioButton.Enabled);
                            break;
                        default:
                            Debug.Assert(true, "Unknown property being set");
                            break;
                    }
                }
                else
                {
                    // Do nothing with property change - 
                    // note that this shouldn't ever happen, we should have
                    // either thrown on the changing event, or we handle above.
                    Debug.Assert(true, "Control property changed notification not handled properly - being ignored");
                }
            }
        }
        // Called when a control currently in the collection 
        // has a property changing - this is 
        // basically to screen out property changes that 
        // cannot occur while the dialog is showing
        // because the Win32 API has no way for us to 
        // propagate the changes until we re-invoke the Win32 call.
        bool IDialogControlHost.IsControlPropertyChangeAllowed(string propertyName, DialogControl control)
        {
            Debug.Assert(control is TaskDialogControl,
                "Property changing for a control that is not a TaskDialogControl-derived type");
            Debug.Assert(propertyName != "Name",
                "Name changes at any time are not supported - public API should have blocked this");

            bool canChange = false;

            if (!NativeDialogShowing)
            {
                // Certain properties can't be changed if the dialog is not showing
                // we need a handle created before we can set these...
                switch (propertyName)
                {
                    case "Enabled":
                        canChange = false;
                        break;
                    default:
                        canChange = true;
                        break;
                }
            }
            else
            {
                // If the dialog is showing, we can only 
                // allow some properties to change.
                switch (propertyName)
                {
                    // Properties that CAN'T be changed while dialog is showing.
                    case "Text":
                    case "Default":
                        canChange = false;
                        break;

                    // Properties that CAN be changed while dialog is showing.
                    case "ShowElevationIcon":
                    case "Enabled":
                        canChange = true;
                        break;
                    default:
                        Debug.Assert(true, "Unknown property name coming through property changing handler");
                        break;
                }
            }
            return canChange;
        }
        // Called when a control currently in the collection
        // has a property changed - this handles propagating
        // the new property values to the Win32 API.
        // If there isn't a way to change the Win32 value, then we
        // should have already screened out the property set
        // in NotifyControlPropertyChanging.
        void IDialogControlHost.ApplyControlPropertyChange(string propertyName, DialogControl control)
        {
            // We only need to apply changes to the
            // native dialog when it actually exists.
            if (NativeDialogShowing)
            {
                TaskDialogButton      button;
                TaskDialogRadioButton radioButton;
                if (control is TaskDialogProgressBar)
                {
                    if (!progressBar.HasValidValues)
                    {
                        throw new ArgumentException(LocalizedMessages.TaskDialogProgressBarValueInRange);
                    }

                    switch (propertyName)
                    {
                    case "State":
                        nativeDialog.UpdateProgressBarState(progressBar.State);
                        break;

                    case "Value":
                        nativeDialog.UpdateProgressBarValue(progressBar.Value);
                        break;

                    case "Minimum":
                    case "Maximum":
                        nativeDialog.UpdateProgressBarRange();
                        break;

                    default:
                        Debug.Assert(true, "Unknown property being set");
                        break;
                    }
                }
                else if ((button = control as TaskDialogButton) != null)
                {
                    switch (propertyName)
                    {
                    case "ShowElevationIcon":
                        nativeDialog.UpdateElevationIcon(button.Id, button.UseElevationIcon);
                        break;

                    case "Enabled":
                        nativeDialog.UpdateButtonEnabled(button.Id, button.Enabled);
                        break;

                    default:
                        Debug.Assert(true, "Unknown property being set");
                        break;
                    }
                }
                else if ((radioButton = control as TaskDialogRadioButton) != null)
                {
                    switch (propertyName)
                    {
                    case "Enabled":
                        nativeDialog.UpdateRadioButtonEnabled(radioButton.Id, radioButton.Enabled);
                        break;

                    default:
                        Debug.Assert(true, "Unknown property being set");
                        break;
                    }
                }
                else
                {
                    // Do nothing with property change -
                    // note that this shouldn't ever happen, we should have
                    // either thrown on the changing event, or we handle above.
                    Debug.Assert(true, "Control property changed notification not handled properly - being ignored");
                }
            }
        }