Advertisement
Guest User

FlexibleMessageBox.cs

a guest
Feb 13th, 2019
1,693
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 44.10 KB | None | 0 0
  1. using System;
  2. using System.Diagnostics;
  3. using System.Drawing;
  4. using System.Globalization;
  5. using System.Linq;
  6. using System.Windows.Forms;
  7.  
  8. namespace JR.Utils.GUI.Forms
  9. {
  10.     /*  FlexibleMessageBox – A flexible replacement for the .NET MessageBox
  11.      *
  12.      *  Author:         Jörg Reichert (public@jreichert.de)
  13.      *  Contributors:   Thanks to: David Hall, Roink
  14.      *  Version:        1.3
  15.      *  Published at:   http://www.codeproject.com/Articles/601900/FlexibleMessageBox
  16.      *  
  17.      ************************************************************************************************************
  18.      * Features:
  19.      *  - It can be simply used instead of MessageBox since all important static "Show"-Functions are supported
  20.      *  - It is small, only one source file, which could be added easily to each solution
  21.      *  - It can be resized and the content is correctly word-wrapped
  22.      *  - It tries to auto-size the width to show the longest text row
  23.      *  - It never exceeds the current desktop working area
  24.      *  - It displays a vertical scrollbar when needed
  25.      *  - It does support hyperlinks in text
  26.      *
  27.      *  Because the interface is identical to MessageBox, you can add this single source file to your project
  28.      *  and use the FlexibleMessageBox almost everywhere you use a standard MessageBox.
  29.      *  The goal was NOT to produce as many features as possible but to provide a simple replacement to fit my
  30.      *  own needs. Feel free to add additional features on your own, but please left my credits in this class.
  31.      *
  32.      ************************************************************************************************************
  33.      * Usage examples:
  34.      *
  35.      *  FlexibleMessageBox.Show("Just a text");
  36.      *
  37.      *  FlexibleMessageBox.Show("A text",
  38.      *                          "A caption");
  39.      *  
  40.      *  FlexibleMessageBox.Show("Some text with a link: www.google.com",
  41.      *                          "Some caption",
  42.      *                          MessageBoxButtons.AbortRetryIgnore,
  43.      *                          MessageBoxIcon.Information,
  44.      *                          MessageBoxDefaultButton.Button2);
  45.      *  
  46.      *  var dialogResult = FlexibleMessageBox.Show("Do you know the answer to life the universe and everything?",
  47.      *                                             "One short question",
  48.      *                                             MessageBoxButtons.YesNo);    
  49.      *
  50.      ************************************************************************************************************
  51.      *  THE SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS", WITHOUT WARRANTY
  52.      *  OF ANY KIND, EXPRESS OR IMPLIED. IN NO EVENT SHALL THE AUTHOR BE
  53.      *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING FROM,
  54.      *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF THIS
  55.      *  SOFTWARE.
  56.      *  
  57.      ************************************************************************************************************
  58.      * History:
  59.      *  Version 1.3 - 19.Dezember 2014
  60.      *  - Added refactoring function GetButtonText()
  61.      *  - Used CurrentUICulture instead of InstalledUICulture
  62.      *  - Added more button localizations. Supported languages are now: ENGLISH, GERMAN, SPANISH, ITALIAN
  63.      *  - Added standard MessageBox handling for "copy to clipboard" with <Ctrl> + <C> and <Ctrl> + <Insert>
  64.      *  - Tab handling is now corrected (only tabbing over the visible buttons)
  65.      *  - Added standard MessageBox handling for ALT-Keyboard shortcuts
  66.      *  - SetDialogSizes: Refactored completely: Corrected sizing and added caption driven sizing
  67.      *
  68.      *  Version 1.2 - 10.August 2013
  69.      *   - Do not ShowInTaskbar anymore (original MessageBox is also hidden in taskbar)
  70.      *   - Added handling for Escape-Button
  71.      *   - Adapted top right close button (red X) to behave like MessageBox (but hidden instead of deactivated)
  72.      *
  73.      *  Version 1.1 - 14.June 2013
  74.      *   - Some Refactoring
  75.      *   - Added internal form class
  76.      *   - Added missing code comments, etc.
  77.      *  
  78.      *  Version 1.0 - 15.April 2013
  79.      *   - Initial Version
  80.     */
  81.     public class FlexibleMessageBox
  82.     {
  83.         #region Public statics
  84.  
  85.         /// <summary>
  86.         /// Defines the maximum width for all FlexibleMessageBox instances in percent of the working area.
  87.         ///
  88.         /// Allowed values are 0.2 - 1.0 where:
  89.         /// 0.2 means:  The FlexibleMessageBox can be at most half as wide as the working area.
  90.         /// 1.0 means:  The FlexibleMessageBox can be as wide as the working area.
  91.         ///
  92.         /// Default is: 70% of the working area width.
  93.         /// </summary>
  94.         public static double MAX_WIDTH_FACTOR = 0.7;
  95.  
  96.         /// <summary>
  97.         /// Defines the maximum height for all FlexibleMessageBox instances in percent of the working area.
  98.         ///
  99.         /// Allowed values are 0.2 - 1.0 where:
  100.         /// 0.2 means:  The FlexibleMessageBox can be at most half as high as the working area.
  101.         /// 1.0 means:  The FlexibleMessageBox can be as high as the working area.
  102.         ///
  103.         /// Default is: 90% of the working area height.
  104.         /// </summary>
  105.         public static double MAX_HEIGHT_FACTOR = 0.9;
  106.  
  107.         /// <summary>
  108.         /// Defines the font for all FlexibleMessageBox instances.
  109.         ///
  110.         /// Default is: SystemFonts.MessageBoxFont
  111.         /// </summary>
  112.         public static Font FONT = SystemFonts.MessageBoxFont;
  113.  
  114.         #endregion
  115.  
  116.         #region Public show functions
  117.  
  118.         /// <summary>
  119.         /// Shows the specified message box.
  120.         /// </summary>
  121.         /// <param name="text">The text.</param>
  122.         /// <returns>The dialog result.</returns>
  123.         public static DialogResult Show(string text)
  124.         {
  125.             return FlexibleMessageBoxForm.Show(null, text, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
  126.         }
  127.  
  128.         /// <summary>
  129.         /// Shows the specified message box.
  130.         /// </summary>
  131.         /// <param name="owner">The owner.</param>
  132.         /// <param name="text">The text.</param>
  133.         /// <returns>The dialog result.</returns>
  134.         public static DialogResult Show(IWin32Window owner, string text)
  135.         {
  136.             return FlexibleMessageBoxForm.Show(owner, text, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
  137.         }
  138.  
  139.         /// <summary>
  140.         /// Shows the specified message box.
  141.         /// </summary>
  142.         /// <param name="text">The text.</param>
  143.         /// <param name="caption">The caption.</param>
  144.         /// <returns>The dialog result.</returns>
  145.         public static DialogResult Show(string text, string caption)
  146.         {
  147.             return FlexibleMessageBoxForm.Show(null, text, caption, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
  148.         }
  149.  
  150.         /// <summary>
  151.         /// Shows the specified message box.
  152.         /// </summary>
  153.         /// <param name="owner">The owner.</param>
  154.         /// <param name="text">The text.</param>
  155.         /// <param name="caption">The caption.</param>
  156.         /// <returns>The dialog result.</returns>
  157.         public static DialogResult Show(IWin32Window owner, string text, string caption)
  158.         {
  159.             return FlexibleMessageBoxForm.Show(owner, text, caption, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
  160.         }
  161.  
  162.         /// <summary>
  163.         /// Shows the specified message box.
  164.         /// </summary>
  165.         /// <param name="text">The text.</param>
  166.         /// <param name="caption">The caption.</param>
  167.         /// <param name="buttons">The buttons.</param>
  168.         /// <returns>The dialog result.</returns>
  169.         public static DialogResult Show(string text, string caption, MessageBoxButtons buttons)
  170.         {
  171.             return FlexibleMessageBoxForm.Show(null, text, caption, buttons, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
  172.         }
  173.  
  174.         /// <summary>
  175.         /// Shows the specified message box.
  176.         /// </summary>
  177.         /// <param name="owner">The owner.</param>
  178.         /// <param name="text">The text.</param>
  179.         /// <param name="caption">The caption.</param>
  180.         /// <param name="buttons">The buttons.</param>
  181.         /// <returns>The dialog result.</returns>
  182.         public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons)
  183.         {
  184.             return FlexibleMessageBoxForm.Show(owner, text, caption, buttons, MessageBoxIcon.None, MessageBoxDefaultButton.Button1);
  185.         }
  186.  
  187.         /// <summary>
  188.         /// Shows the specified message box.
  189.         /// </summary>
  190.         /// <param name="text">The text.</param>
  191.         /// <param name="caption">The caption.</param>
  192.         /// <param name="buttons">The buttons.</param>
  193.         /// <param name="icon">The icon.</param>
  194.         /// <returns></returns>
  195.         public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon)
  196.         {
  197.             return FlexibleMessageBoxForm.Show(null, text, caption, buttons, icon, MessageBoxDefaultButton.Button1);
  198.         }
  199.  
  200.         /// <summary>
  201.         /// Shows the specified message box.
  202.         /// </summary>
  203.         /// <param name="owner">The owner.</param>
  204.         /// <param name="text">The text.</param>
  205.         /// <param name="caption">The caption.</param>
  206.         /// <param name="buttons">The buttons.</param>
  207.         /// <param name="icon">The icon.</param>
  208.         /// <returns>The dialog result.</returns>
  209.         public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon)
  210.         {
  211.             return FlexibleMessageBoxForm.Show(owner, text, caption, buttons, icon, MessageBoxDefaultButton.Button1);
  212.         }
  213.  
  214.         /// <summary>
  215.         /// Shows the specified message box.
  216.         /// </summary>
  217.         /// <param name="text">The text.</param>
  218.         /// <param name="caption">The caption.</param>
  219.         /// <param name="buttons">The buttons.</param>
  220.         /// <param name="icon">The icon.</param>
  221.         /// <param name="defaultButton">The default button.</param>
  222.         /// <returns>The dialog result.</returns>
  223.         public static DialogResult Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
  224.         {
  225.             return FlexibleMessageBoxForm.Show(null, text, caption, buttons, icon, defaultButton);
  226.         }
  227.  
  228.         /// <summary>
  229.         /// Shows the specified message box.
  230.         /// </summary>
  231.         /// <param name="owner">The owner.</param>
  232.         /// <param name="text">The text.</param>
  233.         /// <param name="caption">The caption.</param>
  234.         /// <param name="buttons">The buttons.</param>
  235.         /// <param name="icon">The icon.</param>
  236.         /// <param name="defaultButton">The default button.</param>
  237.         /// <returns>The dialog result.</returns>
  238.         public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
  239.         {
  240.             return FlexibleMessageBoxForm.Show(owner, text, caption, buttons, icon, defaultButton);
  241.         }
  242.  
  243.         #endregion
  244.  
  245.         #region Internal form class
  246.  
  247.         /// <summary>
  248.         /// The form to show the customized message box.
  249.         /// It is defined as an internal class to keep the public interface of the FlexibleMessageBox clean.
  250.         /// </summary>
  251.         class FlexibleMessageBoxForm : Form
  252.         {
  253.             #region Form-Designer generated code
  254.  
  255.             /// <summary>
  256.             /// Erforderliche Designervariable.
  257.             /// </summary>
  258.             private System.ComponentModel.IContainer components = null;
  259.  
  260.             /// <summary>
  261.             /// Verwendete Ressourcen bereinigen.
  262.             /// </summary>
  263.             /// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
  264.             protected override void Dispose(bool disposing)
  265.             {
  266.                 if (disposing && (components != null))
  267.                 {
  268.                     components.Dispose();
  269.                 }
  270.                 base.Dispose(disposing);
  271.             }
  272.  
  273.             /// <summary>
  274.             /// Erforderliche Methode für die Designerunterstützung.
  275.             /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
  276.             /// </summary>
  277.             private void InitializeComponent()
  278.             {
  279.                 this.components = new System.ComponentModel.Container();
  280.                 this.button1 = new System.Windows.Forms.Button();
  281.                 this.richTextBoxMessage = new System.Windows.Forms.RichTextBox();
  282.                 this.FlexibleMessageBoxFormBindingSource = new System.Windows.Forms.BindingSource(this.components);
  283.                 this.panel1 = new System.Windows.Forms.Panel();
  284.                 this.pictureBoxForIcon = new System.Windows.Forms.PictureBox();
  285.                 this.button2 = new System.Windows.Forms.Button();
  286.                 this.button3 = new System.Windows.Forms.Button();
  287.                 ((System.ComponentModel.ISupportInitialize)(this.FlexibleMessageBoxFormBindingSource)).BeginInit();
  288.                 this.panel1.SuspendLayout();
  289.                 ((System.ComponentModel.ISupportInitialize)(this.pictureBoxForIcon)).BeginInit();
  290.                 this.SuspendLayout();
  291.                 //
  292.                 // button1
  293.                 //
  294.                 this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
  295.                 this.button1.AutoSize = true;
  296.                 this.button1.DialogResult = System.Windows.Forms.DialogResult.OK;
  297.                 this.button1.Location = new System.Drawing.Point(11, 67);
  298.                 this.button1.MinimumSize = new System.Drawing.Size(0, 24);
  299.                 this.button1.Name = "button1";
  300.                 this.button1.Size = new System.Drawing.Size(75, 24);
  301.                 this.button1.TabIndex = 2;
  302.                 this.button1.Text = "OK";
  303.                 this.button1.UseVisualStyleBackColor = true;
  304.                 this.button1.Visible = false;
  305.                 //
  306.                 // richTextBoxMessage
  307.                 //
  308.                 this.richTextBoxMessage.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
  309.                 | System.Windows.Forms.AnchorStyles.Left)
  310.                 | System.Windows.Forms.AnchorStyles.Right)));
  311.                 this.richTextBoxMessage.BackColor = System.Drawing.Color.White;
  312.                 this.richTextBoxMessage.BorderStyle = System.Windows.Forms.BorderStyle.None;
  313.                 this.richTextBoxMessage.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.FlexibleMessageBoxFormBindingSource, "MessageText", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
  314.                 this.richTextBoxMessage.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
  315.                 this.richTextBoxMessage.Location = new System.Drawing.Point(50, 26);
  316.                 this.richTextBoxMessage.Margin = new System.Windows.Forms.Padding(0);
  317.                 this.richTextBoxMessage.Name = "richTextBoxMessage";
  318.                 this.richTextBoxMessage.ReadOnly = true;
  319.                 this.richTextBoxMessage.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical;
  320.                 this.richTextBoxMessage.Size = new System.Drawing.Size(200, 20);
  321.                 this.richTextBoxMessage.TabIndex = 0;
  322.                 this.richTextBoxMessage.TabStop = false;
  323.                 this.richTextBoxMessage.Text = "<Message>";
  324.                 this.richTextBoxMessage.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.richTextBoxMessage_LinkClicked);
  325.                 //
  326.                 // panel1
  327.                 //
  328.                 this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
  329.                 | System.Windows.Forms.AnchorStyles.Left)
  330.                 | System.Windows.Forms.AnchorStyles.Right)));
  331.                 this.panel1.BackColor = System.Drawing.Color.White;
  332.                 this.panel1.Controls.Add(this.pictureBoxForIcon);
  333.                 this.panel1.Controls.Add(this.richTextBoxMessage);
  334.                 this.panel1.Location = new System.Drawing.Point(-3, -4);
  335.                 this.panel1.Name = "panel1";
  336.                 this.panel1.Size = new System.Drawing.Size(268, 59);
  337.                 this.panel1.TabIndex = 1;
  338.                 //
  339.                 // pictureBoxForIcon
  340.                 //
  341.                 this.pictureBoxForIcon.BackColor = System.Drawing.Color.Transparent;
  342.                 this.pictureBoxForIcon.Location = new System.Drawing.Point(15, 19);
  343.                 this.pictureBoxForIcon.Name = "pictureBoxForIcon";
  344.                 this.pictureBoxForIcon.Size = new System.Drawing.Size(32, 32);
  345.                 this.pictureBoxForIcon.TabIndex = 8;
  346.                 this.pictureBoxForIcon.TabStop = false;
  347.                 //
  348.                 // button2
  349.                 //
  350.                 this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
  351.                 this.button2.DialogResult = System.Windows.Forms.DialogResult.OK;
  352.                 this.button2.Location = new System.Drawing.Point(92, 67);
  353.                 this.button2.MinimumSize = new System.Drawing.Size(0, 24);
  354.                 this.button2.Name = "button2";
  355.                 this.button2.Size = new System.Drawing.Size(75, 24);
  356.                 this.button2.TabIndex = 3;
  357.                 this.button2.Text = "OK";
  358.                 this.button2.UseVisualStyleBackColor = true;
  359.                 this.button2.Visible = false;
  360.                 //
  361.                 // button3
  362.                 //
  363.                 this.button3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
  364.                 this.button3.AutoSize = true;
  365.                 this.button3.DialogResult = System.Windows.Forms.DialogResult.OK;
  366.                 this.button3.Location = new System.Drawing.Point(173, 67);
  367.                 this.button3.MinimumSize = new System.Drawing.Size(0, 24);
  368.                 this.button3.Name = "button3";
  369.                 this.button3.Size = new System.Drawing.Size(75, 24);
  370.                 this.button3.TabIndex = 0;
  371.                 this.button3.Text = "OK";
  372.                 this.button3.UseVisualStyleBackColor = true;
  373.                 this.button3.Visible = false;
  374.                 //
  375.                 // FlexibleMessageBoxForm
  376.                 //
  377.                 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
  378.                 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
  379.                 this.ClientSize = new System.Drawing.Size(260, 102);
  380.                 this.Controls.Add(this.button3);
  381.                 this.Controls.Add(this.button2);
  382.                 this.Controls.Add(this.panel1);
  383.                 this.Controls.Add(this.button1);
  384.                 this.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.FlexibleMessageBoxFormBindingSource, "CaptionText", true));
  385.                 this.MaximizeBox = false;
  386.                 this.MinimizeBox = false;
  387.                 this.MinimumSize = new System.Drawing.Size(276, 140);
  388.                 this.Name = "FlexibleMessageBoxForm";
  389.                 this.ShowIcon = false;
  390.                 this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show;
  391.                 this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
  392.                 this.Text = "<Caption>";
  393.                 this.Shown += new System.EventHandler(this.FlexibleMessageBoxForm_Shown);
  394.                 ((System.ComponentModel.ISupportInitialize)(this.FlexibleMessageBoxFormBindingSource)).EndInit();
  395.                 this.panel1.ResumeLayout(false);
  396.                 ((System.ComponentModel.ISupportInitialize)(this.pictureBoxForIcon)).EndInit();
  397.                 this.ResumeLayout(false);
  398.                 this.PerformLayout();
  399.             }
  400.  
  401.             private System.Windows.Forms.Button button1;
  402.             private System.Windows.Forms.BindingSource FlexibleMessageBoxFormBindingSource;
  403.             private System.Windows.Forms.RichTextBox richTextBoxMessage;
  404.             private System.Windows.Forms.Panel panel1;
  405.             private System.Windows.Forms.PictureBox pictureBoxForIcon;
  406.             private System.Windows.Forms.Button button2;
  407.             private System.Windows.Forms.Button button3;
  408.  
  409.             #endregion
  410.  
  411.             #region Private constants
  412.  
  413.             //These separators are used for the "copy to clipboard" standard operation, triggered by Ctrl + C (behavior and clipboard format is like in a standard MessageBox)
  414.             private static readonly String STANDARD_MESSAGEBOX_SEPARATOR_LINES = "---------------------------\n";
  415.             private static readonly String STANDARD_MESSAGEBOX_SEPARATOR_SPACES = "   ";
  416.  
  417.             //These are the possible buttons (in a standard MessageBox)
  418.             private enum ButtonID { OK = 0, CANCEL, YES, NO, ABORT, RETRY, IGNORE };
  419.            
  420.             //These are the buttons texts for different languages.
  421.             //If you want to add a new language, add it here and in the GetButtonText-Function
  422.             private enum TwoLetterISOLanguageID { en, de, es, it };
  423.             private static readonly String[] BUTTON_TEXTS_ENGLISH_EN = { "OK", "Cancel", "&Yes", "&No", "&Abort", "&Retry", "&Ignore" }; //Note: This is also the fallback language
  424.             private static readonly String[] BUTTON_TEXTS_GERMAN_DE = { "OK", "Abbrechen", "&Ja", "&Nein", "&Abbrechen", "&Wiederholen", "&Ignorieren" };
  425.             private static readonly String[] BUTTON_TEXTS_SPANISH_ES = { "Aceptar", "Cancelar", "&Sí", "&No", "&Abortar", "&Reintentar", "&Ignorar" };
  426.             private static readonly String[] BUTTON_TEXTS_ITALIAN_IT = { "OK", "Annulla", "&Sì", "&No", "&Interrompi", "&Riprova", "&Ignora" };
  427.  
  428.             #endregion
  429.  
  430.             #region Private members
  431.  
  432.             private MessageBoxDefaultButton defaultButton;
  433.             private int visibleButtonsCount;
  434.             private TwoLetterISOLanguageID languageID = TwoLetterISOLanguageID.en;
  435.  
  436.             #endregion
  437.  
  438.             #region Private constructor
  439.  
  440.             /// <summary>
  441.             /// Initializes a new instance of the <see cref="FlexibleMessageBoxForm"/> class.
  442.             /// </summary>
  443.             private FlexibleMessageBoxForm()
  444.             {
  445.                 InitializeComponent();
  446.  
  447.                 //Try to evaluate the language. If this fails, the fallback language English will be used
  448.                 Enum.TryParse<TwoLetterISOLanguageID>(CultureInfo.CurrentUICulture.TwoLetterISOLanguageName, out this.languageID);
  449.  
  450.                 this.KeyPreview = true;
  451.                 this.KeyUp += FlexibleMessageBoxForm_KeyUp;
  452.             }
  453.  
  454.             #endregion
  455.  
  456.             #region Private helper functions
  457.  
  458.             /// <summary>
  459.             /// Gets the string rows.
  460.             /// </summary>
  461.             /// <param name="message">The message.</param>
  462.             /// <returns>The string rows as 1-dimensional array</returns>
  463.             private static string[] GetStringRows(string message)
  464.             {
  465.                 if (string.IsNullOrEmpty(message)) return null;
  466.  
  467.                 var messageRows = message.Split(new char[] { '\n' }, StringSplitOptions.None);
  468.                 return messageRows;
  469.             }
  470.  
  471.             /// <summary>
  472.             /// Gets the button text for the CurrentUICulture language.
  473.             /// Note: The fallback language is English
  474.             /// </summary>
  475.             /// <param name="buttonID">The ID of the button.</param>
  476.             /// <returns>The button text</returns>
  477.             private string GetButtonText(ButtonID buttonID)
  478.             {
  479.                 var buttonTextArrayIndex = Convert.ToInt32(buttonID);
  480.                
  481.                 switch (this.languageID)
  482.                 {
  483.                     case TwoLetterISOLanguageID.de: return BUTTON_TEXTS_GERMAN_DE[buttonTextArrayIndex];
  484.                     case TwoLetterISOLanguageID.es: return BUTTON_TEXTS_SPANISH_ES[buttonTextArrayIndex];
  485.                     case TwoLetterISOLanguageID.it: return BUTTON_TEXTS_ITALIAN_IT[buttonTextArrayIndex];
  486.  
  487.                     default:                        return BUTTON_TEXTS_ENGLISH_EN[buttonTextArrayIndex];
  488.                 }
  489.             }
  490.  
  491.             /// <summary>
  492.             /// Ensure the given working area factor in the range of  0.2 - 1.0 where:
  493.             ///
  494.             /// 0.2 means:  20 percent of the working area height or width.
  495.             /// 1.0 means:  100 percent of the working area height or width.
  496.             /// </summary>
  497.             /// <param name="workingAreaFactor">The given working area factor.</param>
  498.             /// <returns>The corrected given working area factor.</returns>
  499.             private static double GetCorrectedWorkingAreaFactor(double workingAreaFactor)
  500.             {
  501.                 const double MIN_FACTOR = 0.2;
  502.                 const double MAX_FACTOR = 1.0;
  503.  
  504.                 if (workingAreaFactor < MIN_FACTOR) return MIN_FACTOR;
  505.                 if (workingAreaFactor > MAX_FACTOR) return MAX_FACTOR;
  506.  
  507.                 return workingAreaFactor;
  508.             }
  509.  
  510.             /// <summary>
  511.             /// Set the dialogs start position when given.
  512.             /// Otherwise center the dialog on the current screen.
  513.             /// </summary>
  514.             /// <param name="flexibleMessageBoxForm">The FlexibleMessageBox dialog.</param>
  515.             /// <param name="owner">The owner.</param>
  516.             private static void SetDialogStartPosition(FlexibleMessageBoxForm flexibleMessageBoxForm, IWin32Window owner)
  517.             {
  518.                 //If no owner given: Center on current screen
  519.                 if (owner == null)
  520.                 {
  521.                     var screen = Screen.FromPoint(Cursor.Position);
  522.                     flexibleMessageBoxForm.StartPosition = FormStartPosition.Manual;
  523.                     flexibleMessageBoxForm.Left = screen.Bounds.Left + screen.Bounds.Width / 2 - flexibleMessageBoxForm.Width / 2;
  524.                     flexibleMessageBoxForm.Top = screen.Bounds.Top + screen.Bounds.Height / 2 - flexibleMessageBoxForm.Height / 2;
  525.                 }
  526.             }
  527.  
  528.             /// <summary>
  529.             /// Calculate the dialogs start size (Try to auto-size width to show longest text row).
  530.             /// Also set the maximum dialog size.
  531.             /// </summary>
  532.             /// <param name="flexibleMessageBoxForm">The FlexibleMessageBox dialog.</param>
  533.             /// <param name="text">The text (the longest text row is used to calculate the dialog width).</param>
  534.             /// <param name="text">The caption (this can also affect the dialog width).</param>
  535.             private static void SetDialogSizes(FlexibleMessageBoxForm flexibleMessageBoxForm, string text, string caption)
  536.             {
  537.                 //First set the bounds for the maximum dialog size
  538.                 flexibleMessageBoxForm.MaximumSize = new Size(Convert.ToInt32(SystemInformation.WorkingArea.Width * FlexibleMessageBoxForm.GetCorrectedWorkingAreaFactor(MAX_WIDTH_FACTOR)),
  539.                                                               Convert.ToInt32(SystemInformation.WorkingArea.Height * FlexibleMessageBoxForm.GetCorrectedWorkingAreaFactor(MAX_HEIGHT_FACTOR)));
  540.  
  541.                 //Get rows. Exit if there are no rows to render...
  542.                 var stringRows = GetStringRows(text);
  543.                 if (stringRows == null) return;
  544.  
  545.                 //Calculate whole text height
  546.                 var textHeight = TextRenderer.MeasureText(text, FONT).Height;
  547.                    
  548.                 //Calculate width for longest text line
  549.                 const int SCROLLBAR_WIDTH_OFFSET = 15;
  550.                 var longestTextRowWidth = stringRows.Max(textForRow => TextRenderer.MeasureText(textForRow, FONT).Width);
  551.                 var captionWidth = TextRenderer.MeasureText(caption, SystemFonts.CaptionFont).Width;
  552.                 var textWidth = Math.Max(longestTextRowWidth + SCROLLBAR_WIDTH_OFFSET, captionWidth);
  553.                
  554.                 //Calculate margins
  555.                 var marginWidth = flexibleMessageBoxForm.Width - flexibleMessageBoxForm.richTextBoxMessage.Width;
  556.                 var marginHeight = flexibleMessageBoxForm.Height - flexibleMessageBoxForm.richTextBoxMessage.Height;
  557.  
  558.                 //Set calculated dialog size (if the calculated values exceed the maximums, they were cut by windows forms automatically)
  559.                 flexibleMessageBoxForm.Size = new Size(textWidth + marginWidth,
  560.                                                        textHeight + marginHeight);
  561.             }
  562.  
  563.             /// <summary>
  564.             /// Set the dialogs icon.
  565.             /// When no icon is used: Correct placement and width of rich text box.
  566.             /// </summary>
  567.             /// <param name="flexibleMessageBoxForm">The FlexibleMessageBox dialog.</param>
  568.             /// <param name="icon">The MessageBoxIcon.</param>
  569.             private static void SetDialogIcon(FlexibleMessageBoxForm flexibleMessageBoxForm, MessageBoxIcon icon)
  570.             {
  571.                 switch (icon)
  572.                 {
  573.                     case MessageBoxIcon.Information:
  574.                         flexibleMessageBoxForm.pictureBoxForIcon.Image = SystemIcons.Information.ToBitmap();
  575.                         break;
  576.                     case MessageBoxIcon.Warning:
  577.                         flexibleMessageBoxForm.pictureBoxForIcon.Image = SystemIcons.Warning.ToBitmap();
  578.                         break;
  579.                     case MessageBoxIcon.Error:
  580.                         flexibleMessageBoxForm.pictureBoxForIcon.Image = SystemIcons.Error.ToBitmap();
  581.                         break;
  582.                     case MessageBoxIcon.Question:
  583.                         flexibleMessageBoxForm.pictureBoxForIcon.Image = SystemIcons.Question.ToBitmap();
  584.                         break;
  585.                     default:
  586.                         //When no icon is used: Correct placement and width of rich text box.
  587.                         flexibleMessageBoxForm.pictureBoxForIcon.Visible = false;
  588.                         flexibleMessageBoxForm.richTextBoxMessage.Left -= flexibleMessageBoxForm.pictureBoxForIcon.Width;
  589.                         flexibleMessageBoxForm.richTextBoxMessage.Width += flexibleMessageBoxForm.pictureBoxForIcon.Width;
  590.                         break;
  591.                 }
  592.             }
  593.  
  594.             /// <summary>
  595.             /// Set dialog buttons visibilities and texts.
  596.             /// Also set a default button.
  597.             /// </summary>
  598.             /// <param name="flexibleMessageBoxForm">The FlexibleMessageBox dialog.</param>
  599.             /// <param name="buttons">The buttons.</param>
  600.             /// <param name="defaultButton">The default button.</param>
  601.             private static void SetDialogButtons(FlexibleMessageBoxForm flexibleMessageBoxForm, MessageBoxButtons buttons, MessageBoxDefaultButton defaultButton)
  602.             {
  603.                 //Set the buttons visibilities and texts
  604.                 switch (buttons)
  605.                 {
  606.                     case MessageBoxButtons.AbortRetryIgnore:
  607.                         flexibleMessageBoxForm.visibleButtonsCount = 3;
  608.  
  609.                         flexibleMessageBoxForm.button1.Visible = true;
  610.                         flexibleMessageBoxForm.button1.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.ABORT);
  611.                         flexibleMessageBoxForm.button1.DialogResult = DialogResult.Abort;
  612.  
  613.                         flexibleMessageBoxForm.button2.Visible = true;
  614.                         flexibleMessageBoxForm.button2.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.RETRY);
  615.                         flexibleMessageBoxForm.button2.DialogResult = DialogResult.Retry;
  616.  
  617.                         flexibleMessageBoxForm.button3.Visible = true;
  618.                         flexibleMessageBoxForm.button3.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.IGNORE);
  619.                         flexibleMessageBoxForm.button3.DialogResult = DialogResult.Ignore;
  620.                        
  621.                         flexibleMessageBoxForm.ControlBox = false;
  622.                         break;
  623.  
  624.                     case MessageBoxButtons.OKCancel:
  625.                         flexibleMessageBoxForm.visibleButtonsCount = 2;
  626.  
  627.                         flexibleMessageBoxForm.button2.Visible = true;
  628.                         flexibleMessageBoxForm.button2.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.OK);
  629.                         flexibleMessageBoxForm.button2.DialogResult = DialogResult.OK;
  630.  
  631.                         flexibleMessageBoxForm.button3.Visible = true;
  632.                         flexibleMessageBoxForm.button3.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.CANCEL);
  633.                         flexibleMessageBoxForm.button3.DialogResult = DialogResult.Cancel;
  634.  
  635.                         flexibleMessageBoxForm.CancelButton = flexibleMessageBoxForm.button3;
  636.                         break;
  637.  
  638.                     case MessageBoxButtons.RetryCancel:
  639.                         flexibleMessageBoxForm.visibleButtonsCount = 2;
  640.  
  641.                         flexibleMessageBoxForm.button2.Visible = true;
  642.                         flexibleMessageBoxForm.button2.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.RETRY);
  643.                         flexibleMessageBoxForm.button2.DialogResult = DialogResult.Retry;
  644.  
  645.                         flexibleMessageBoxForm.button3.Visible = true;
  646.                         flexibleMessageBoxForm.button3.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.CANCEL);
  647.                         flexibleMessageBoxForm.button3.DialogResult = DialogResult.Cancel;
  648.  
  649.                         flexibleMessageBoxForm.CancelButton = flexibleMessageBoxForm.button3;
  650.                         break;
  651.  
  652.                     case MessageBoxButtons.YesNo:
  653.                         flexibleMessageBoxForm.visibleButtonsCount = 2;
  654.  
  655.                         flexibleMessageBoxForm.button2.Visible = true;
  656.                         flexibleMessageBoxForm.button2.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.YES);
  657.                         flexibleMessageBoxForm.button2.DialogResult = DialogResult.Yes;
  658.  
  659.                         flexibleMessageBoxForm.button3.Visible = true;
  660.                         flexibleMessageBoxForm.button3.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.NO);
  661.                         flexibleMessageBoxForm.button3.DialogResult = DialogResult.No;
  662.  
  663.                         flexibleMessageBoxForm.ControlBox = false;
  664.                         break;
  665.  
  666.                     case MessageBoxButtons.YesNoCancel:
  667.                         flexibleMessageBoxForm.visibleButtonsCount = 3;
  668.  
  669.                         flexibleMessageBoxForm.button1.Visible = true;
  670.                         flexibleMessageBoxForm.button1.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.YES);
  671.                         flexibleMessageBoxForm.button1.DialogResult = DialogResult.Yes;
  672.  
  673.                         flexibleMessageBoxForm.button2.Visible = true;
  674.                         flexibleMessageBoxForm.button2.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.NO);
  675.                         flexibleMessageBoxForm.button2.DialogResult = DialogResult.No;
  676.  
  677.                         flexibleMessageBoxForm.button3.Visible = true;
  678.                         flexibleMessageBoxForm.button3.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.CANCEL);
  679.                         flexibleMessageBoxForm.button3.DialogResult = DialogResult.Cancel;
  680.  
  681.                         flexibleMessageBoxForm.CancelButton = flexibleMessageBoxForm.button3;
  682.                         break;
  683.  
  684.                     case MessageBoxButtons.OK:
  685.                     default:
  686.                         flexibleMessageBoxForm.visibleButtonsCount = 1;
  687.                         flexibleMessageBoxForm.button3.Visible = true;
  688.                         flexibleMessageBoxForm.button3.Text = flexibleMessageBoxForm.GetButtonText(ButtonID.OK);
  689.                         flexibleMessageBoxForm.button3.DialogResult = DialogResult.OK;
  690.  
  691.                         flexibleMessageBoxForm.CancelButton = flexibleMessageBoxForm.button3;
  692.                         break;
  693.                 }
  694.  
  695.                 //Set default button (used in FlexibleMessageBoxForm_Shown)
  696.                 flexibleMessageBoxForm.defaultButton = defaultButton;
  697.             }
  698.  
  699.             #endregion
  700.  
  701.             #region Private event handlers
  702.  
  703.             /// <summary>
  704.             /// Handles the Shown event of the FlexibleMessageBoxForm control.
  705.             /// </summary>
  706.             /// <param name="sender">The source of the event.</param>
  707.             /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
  708.             private void FlexibleMessageBoxForm_Shown(object sender, EventArgs e)
  709.             {
  710.                 int buttonIndexToFocus = 1;
  711.                 Button buttonToFocus;
  712.  
  713.                 //Set the default button...
  714.                 switch (this.defaultButton)
  715.                 {
  716.                     case MessageBoxDefaultButton.Button1:
  717.                     default:
  718.                         buttonIndexToFocus = 1;
  719.                         break;
  720.                     case MessageBoxDefaultButton.Button2:
  721.                         buttonIndexToFocus = 2;
  722.                         break;
  723.                     case MessageBoxDefaultButton.Button3:
  724.                         buttonIndexToFocus = 3;
  725.                         break;
  726.                 }
  727.  
  728.                 if (buttonIndexToFocus > this.visibleButtonsCount) buttonIndexToFocus = this.visibleButtonsCount;
  729.  
  730.                 if (buttonIndexToFocus == 3)
  731.                 {
  732.                     buttonToFocus = this.button3;
  733.                 }
  734.                 else if (buttonIndexToFocus == 2)
  735.                 {
  736.                     buttonToFocus = this.button2;
  737.                 }
  738.                 else
  739.                 {
  740.                     buttonToFocus = this.button1;
  741.                 }
  742.  
  743.                 buttonToFocus.Focus();
  744.             }
  745.  
  746.             /// <summary>
  747.             /// Handles the LinkClicked event of the richTextBoxMessage control.
  748.             /// </summary>
  749.             /// <param name="sender">The source of the event.</param>
  750.             /// <param name="e">The <see cref="System.Windows.Forms.LinkClickedEventArgs"/> instance containing the event data.</param>
  751.             private void richTextBoxMessage_LinkClicked(object sender, LinkClickedEventArgs e)
  752.             {
  753.                 try
  754.                 {
  755.                     Cursor.Current = Cursors.WaitCursor;
  756.                     Process.Start(e.LinkText);
  757.                 }
  758.                 catch (Exception)
  759.                 {
  760.                     //Let the caller of FlexibleMessageBoxForm decide what to do with this exception...
  761.                     throw;
  762.                 }
  763.                 finally
  764.                 {
  765.                     Cursor.Current = Cursors.Default;
  766.                 }
  767.  
  768.             }
  769.  
  770.             /// <summary>
  771.             /// Handles the KeyUp event of the richTextBoxMessage control.
  772.             /// </summary>
  773.             /// <param name="sender">The source of the event.</param>
  774.             /// <param name="e">The <see cref="System.Windows.Forms.KeyEventArgs"/> instance containing the event data.</param>
  775.             void FlexibleMessageBoxForm_KeyUp(object sender, KeyEventArgs e)
  776.             {
  777.                 //Handle standard key strikes for clipboard copy: "Ctrl + C" and "Ctrl + Insert"
  778.                 if (e.Control && (e.KeyCode == Keys.C || e.KeyCode == Keys.Insert))
  779.                 {
  780.                     var buttonsTextLine = (this.button1.Visible ? this.button1.Text + STANDARD_MESSAGEBOX_SEPARATOR_SPACES : string.Empty)
  781.                                         + (this.button2.Visible ? this.button2.Text + STANDARD_MESSAGEBOX_SEPARATOR_SPACES : string.Empty)
  782.                                         + (this.button3.Visible ? this.button3.Text + STANDARD_MESSAGEBOX_SEPARATOR_SPACES : string.Empty);
  783.  
  784.                     //Build same clipboard text like the standard .Net MessageBox
  785.                     var textForClipboard = STANDARD_MESSAGEBOX_SEPARATOR_LINES
  786.                                          + this.Text + Environment.NewLine
  787.                                          + STANDARD_MESSAGEBOX_SEPARATOR_LINES
  788.                                          + this.richTextBoxMessage.Text + Environment.NewLine
  789.                                          + STANDARD_MESSAGEBOX_SEPARATOR_LINES
  790.                                          + buttonsTextLine.Replace("&", string.Empty) + Environment.NewLine
  791.                                          + STANDARD_MESSAGEBOX_SEPARATOR_LINES;
  792.  
  793.                     //Set text in clipboard
  794.                     Clipboard.SetText(textForClipboard);
  795.                 }
  796.             }
  797.  
  798.             #endregion
  799.  
  800.             #region Properties (only used for binding)
  801.  
  802.             /// <summary>
  803.             /// The text that is been used for the heading.
  804.             /// </summary>
  805.             public string CaptionText { get; set; }
  806.  
  807.             /// <summary>
  808.             /// The text that is been used in the FlexibleMessageBoxForm.
  809.             /// </summary>
  810.             public string MessageText { get; set; }
  811.  
  812.             #endregion
  813.  
  814.             #region Public show function
  815.  
  816.             /// <summary>
  817.             /// Shows the specified message box.
  818.             /// </summary>
  819.             /// <param name="owner">The owner.</param>
  820.             /// <param name="text">The text.</param>
  821.             /// <param name="caption">The caption.</param>
  822.             /// <param name="buttons">The buttons.</param>
  823.             /// <param name="icon">The icon.</param>
  824.             /// <param name="defaultButton">The default button.</param>
  825.             /// <returns>The dialog result.</returns>
  826.             public static DialogResult Show(IWin32Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
  827.             {
  828.                 //Create a new instance of the FlexibleMessageBox form
  829.                 var flexibleMessageBoxForm = new FlexibleMessageBoxForm();
  830.                 flexibleMessageBoxForm.ShowInTaskbar = false;
  831.  
  832.                 //Bind the caption and the message text
  833.                 flexibleMessageBoxForm.CaptionText = caption;
  834.                 flexibleMessageBoxForm.MessageText = text;
  835.                 flexibleMessageBoxForm.FlexibleMessageBoxFormBindingSource.DataSource = flexibleMessageBoxForm;
  836.  
  837.                 //Set the buttons visibilities and texts. Also set a default button.
  838.                 SetDialogButtons(flexibleMessageBoxForm, buttons, defaultButton);
  839.  
  840.                 //Set the dialogs icon. When no icon is used: Correct placement and width of rich text box.
  841.                 SetDialogIcon(flexibleMessageBoxForm, icon);
  842.  
  843.                 //Set the font for all controls
  844.                 flexibleMessageBoxForm.Font = FONT;
  845.                 flexibleMessageBoxForm.richTextBoxMessage.Font = FONT;
  846.  
  847.                 //Calculate the dialogs start size (Try to auto-size width to show longest text row). Also set the maximum dialog size.
  848.                 SetDialogSizes(flexibleMessageBoxForm, text, caption);
  849.  
  850.                 //Set the dialogs start position when given. Otherwise center the dialog on the current screen.
  851.                 SetDialogStartPosition(flexibleMessageBoxForm, owner);
  852.  
  853.                 //Show the dialog
  854.                 return flexibleMessageBoxForm.ShowDialog(owner);
  855.             }
  856.  
  857.             #endregion
  858.         } //class FlexibleMessageBoxForm
  859.  
  860.         #endregion
  861.     }
  862. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement