/// <summary>
        /// Setup the MessageBoxViewModel with the information it needs
        /// </summary>
        /// <param name="messageBoxText">A System.String that specifies the text to display.</param>
        /// <param name="caption">A System.String that specifies the title bar caption to display.</param>
        /// <param name="buttons">A System.Windows.MessageBoxButton value that specifies which button or buttons to display.</param>
        /// <param name="icon">A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
        /// <param name="defaultResult">A System.Windows.MessageBoxResult value that specifies the default result of the message box.</param>
        /// <param name="cancelResult">A System.Windows.MessageBoxResult value that specifies the cancel result of the message box</param>
        /// <param name="options">A System.Windows.MessageBoxOptions value object that specifies the options.</param>
        /// <param name="buttonLabels">A dictionary specifying the button labels, if desirable</param>
        public void Setup(
            string messageBoxText,
            string caption                 = null,
            MessageBoxButton buttons       = MessageBoxButton.OK,
            MessageBoxImage icon           = MessageBoxImage.None,
            MessageBoxResult defaultResult = MessageBoxResult.None,
            MessageBoxResult cancelResult  = MessageBoxResult.None,
            MessageBoxOptions options      = MessageBoxOptions.None,
            IDictionary <MessageBoxResult, string> buttonLabels = null)
        {
            this.Text        = messageBoxText;
            this.DisplayName = caption;
            this.Icon        = icon;

            var buttonList = new BindableCollection <LabelledValue <MessageBoxResult> >();

            this.ButtonList = buttonList;
            foreach (var val in ButtonToResults[buttons])
            {
                string label;
                if (buttonLabels == null || !buttonLabels.TryGetValue(val, out label))
                {
                    label = ButtonLabels[val];
                }

                var lbv = new LabelledValue <MessageBoxResult>(label, val);
                buttonList.Add(lbv);
                if (val == defaultResult)
                {
                    this.DefaultButton = lbv;
                }
                else if (val == cancelResult)
                {
                    this.CancelButton = lbv;
                }
            }
            // If they didn't specify a button which we showed, then pick a default, if we can
            if (this.DefaultButton == null)
            {
                if (defaultResult == MessageBoxResult.None && this.ButtonList.Any())
                {
                    this.DefaultButton = buttonList[0];
                }
                else
                {
                    throw new ArgumentException("DefaultButton set to a button which doesn't appear in Buttons");
                }
            }
            if (this.CancelButton == null)
            {
                if (cancelResult == MessageBoxResult.None && this.ButtonList.Any())
                {
                    this.CancelButton = buttonList.Last();
                }
                else
                {
                    throw new ArgumentException("CancelButton set to a button which doesn't appear in Buttons");
                }
            }

            this.FlowDirection = options.HasFlag(MessageBoxOptions.RtlReading) ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
            this.TextAlignment = (options.HasFlag(MessageBoxOptions.RightAlign) == options.HasFlag(MessageBoxOptions.RtlReading)) ? TextAlignment.Left : TextAlignment.Right;
        }
        /// <summary>
        /// Setup the MessageBoxViewModel with the information it needs
        /// </summary>
        /// <param name="messageBoxText">A System.String that specifies the text to display.</param>
        /// <param name="caption">A System.String that specifies the title bar caption to display.</param>
        /// <param name="buttons">A System.Windows.MessageBoxButton value that specifies which button or buttons to display.</param>
        /// <param name="icon">A System.Windows.MessageBoxImage value that specifies the icon to display.</param>
        /// <param name="defaultResult">A System.Windows.MessageBoxResult value that specifies the default result of the message box.</param>
        /// <param name="cancelResult">A System.Windows.MessageBoxResult value that specifies the cancel result of the message box</param>
        /// <param name="options">A System.Windows.MessageBoxOptions value object that specifies the options.</param>
        /// <param name="buttonLabels">A dictionary specifying the button labels, if desirable</param>
        public void Setup(
            string messageBoxText,
            string caption = null,
            MessageBoxButton buttons = MessageBoxButton.OK,
            MessageBoxImage icon = MessageBoxImage.None,
            MessageBoxResult defaultResult = MessageBoxResult.None,
            MessageBoxResult cancelResult = MessageBoxResult.None,
            MessageBoxOptions options = MessageBoxOptions.None,
            IDictionary<MessageBoxResult, string> buttonLabels = null)
        {
            this.Text = messageBoxText;
            this.DisplayName = caption;
            this.Icon = icon;

            var buttonList = new BindableCollection<LabelledValue<MessageBoxResult>>();
            this.ButtonList = buttonList;
            foreach (var val in ButtonToResults[buttons])
            {
                string label;
                if (buttonLabels == null || !buttonLabels.TryGetValue(val, out label))
                    label = ButtonLabels[val];
                    
                var lbv = new LabelledValue<MessageBoxResult>(label, val);
                buttonList.Add(lbv);
                if (val == defaultResult)
                    this.DefaultButton = lbv;
                else if (val == cancelResult)
                    this.CancelButton = lbv;
            }
            // If they didn't specify a button which we showed, then pick a default, if we can
            if (this.DefaultButton == null)
            {
                if (defaultResult == MessageBoxResult.None && this.ButtonList.Any())
                    this.DefaultButton = buttonList[0];
                else
                    throw new ArgumentException("DefaultButton set to a button which doesn't appear in Buttons");
            }
            if (this.CancelButton == null)
            {
                if (cancelResult == MessageBoxResult.None && this.ButtonList.Any())
                    this.CancelButton = buttonList.Last();
                else
                    throw new ArgumentException("CancelButton set to a button which doesn't appear in Buttons");
            }

            this.FlowDirection = options.HasFlag(MessageBoxOptions.RtlReading) ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
            this.TextAlignment = (options.HasFlag(MessageBoxOptions.RightAlign) == options.HasFlag(MessageBoxOptions.RtlReading)) ? TextAlignment.Left : TextAlignment.Right;
        }
        private ScrollableMessageBox(string text, string caption = null, MessageBoxButtons buttons = MessageBoxButtons.OK, MessageBoxIcon icon = MessageBoxIcon.None, MessageBoxDefaultButton defButton = MessageBoxDefaultButton.Button1, MessageBoxOptions options = 0)
        {
            if (text == null)
            {
                throw new ArgumentNullException(nameof(text));
            }

            InitializeComponent();
            this.UpdateLightDarkMode();

            txtText.Text = text;
            txtText.AutoSetScrollbars();
            Text         = string.IsNullOrWhiteSpace(caption) ? string.Empty : caption;
            _eBoxButtons = buttons;
            switch (buttons)
            {
            case MessageBoxButtons.OK:
                cmdButton1.Text = NativeMethods.GetSystemString(NativeMethods.SystemString.OK);
                tlpButtons.Controls.Remove(cmdButton2);
                tlpButtons.Controls.Remove(cmdButton3);
                cmdButton2.Dispose();
                cmdButton2 = null;
                cmdButton3.Dispose();
                cmdButton3 = null;
                break;

            case MessageBoxButtons.OKCancel:
                cmdButton1.Text = NativeMethods.GetSystemString(NativeMethods.SystemString.Cancel);
                cmdButton2.Text = NativeMethods.GetSystemString(NativeMethods.SystemString.OK);
                tlpButtons.Controls.Remove(cmdButton3);
                cmdButton3.Dispose();
                cmdButton3 = null;
                break;

            case MessageBoxButtons.AbortRetryIgnore:
                cmdButton1.Text = NativeMethods.GetSystemString(NativeMethods.SystemString.Ignore);
                cmdButton2.Text = NativeMethods.GetSystemString(NativeMethods.SystemString.Retry);
                cmdButton3.Text = NativeMethods.GetSystemString(NativeMethods.SystemString.Abort);
                break;

            case MessageBoxButtons.YesNoCancel:
                cmdButton1.Text = NativeMethods.GetSystemString(NativeMethods.SystemString.Cancel);
                cmdButton2.Text = NativeMethods.GetSystemString(NativeMethods.SystemString.No);
                cmdButton3.Text = NativeMethods.GetSystemString(NativeMethods.SystemString.Yes);
                break;

            case MessageBoxButtons.YesNo:
                cmdButton1.Text = NativeMethods.GetSystemString(NativeMethods.SystemString.No);
                cmdButton2.Text = NativeMethods.GetSystemString(NativeMethods.SystemString.Yes);
                tlpButtons.Controls.Remove(cmdButton3);
                cmdButton3.Dispose();
                cmdButton3 = null;
                break;

            case MessageBoxButtons.RetryCancel:
                cmdButton1.Text = NativeMethods.GetSystemString(NativeMethods.SystemString.Cancel);
                cmdButton2.Text = NativeMethods.GetSystemString(NativeMethods.SystemString.Retry);
                tlpButtons.Controls.Remove(cmdButton3);
                cmdButton3.Dispose();
                cmdButton3 = null;
                break;
            }

            switch (icon)
            {
            case MessageBoxIcon.None:
                imgIcon.Visible = false;
                break;

            case MessageBoxIcon.Error:
                imgIcon.Image = Utils.StockIconBitmapsForSystemIcons[SystemIcons.Error];
                break;

            case MessageBoxIcon.Question:
                imgIcon.Image = Utils.StockIconBitmapsForSystemIcons[SystemIcons.Question];
                break;

            case MessageBoxIcon.Warning:
                imgIcon.Image = Utils.StockIconBitmapsForSystemIcons[SystemIcons.Warning];
                break;

            case MessageBoxIcon.Information:
                imgIcon.Image = Utils.StockIconBitmapsForSystemIcons[SystemIcons.Information];
                break;
            }

            if (options.HasFlag(MessageBoxOptions.ServiceNotification) || options.HasFlag(MessageBoxOptions.DefaultDesktopOnly))
            {
                StartPosition = FormStartPosition.CenterScreen;
            }
            if (options.HasFlag(MessageBoxOptions.RightAlign))
            {
                txtText.TextAlign = HorizontalAlignment.Right;
            }
            if (options.HasFlag(MessageBoxOptions.RtlReading))
            {
                txtText.RightToLeft = RightToLeft.Yes;
            }

            switch (defButton)
            {
            case MessageBoxDefaultButton.Button2:
                if (cmdButton2 != null)
                {
                    cmdButton2.Focus();
                }
                else
                {
                    cmdButton1.Focus();
                }
                break;

            case MessageBoxDefaultButton.Button3:
                cmdButton1.Focus();
                break;

            default:
                if (cmdButton3 != null)
                {
                    cmdButton3.Focus();
                }
                else if (cmdButton2 != null)
                {
                    cmdButton2.Focus();
                }
                else
                {
                    cmdButton1.Focus();
                }
                break;
            }
        }