2010-09-17 11 views
15

Robię aplikację C# i chcę zmienić styl okna komunikatu. Czy to możliwe, czy nie?Dostosowywanie okna komunikatu

Przykład: zmiana przycisk styl, przód kolor itp

+6

Niepoprawny pomysł, ważne są ramki wiadomości o spójnym wyglądzie i odczuciu. Zdecyduj się na odpowiedź "co do cholery jest teraz" od użytkownika i sprawia, że ​​prawdopodobnie przeczyta ona wiadomość i kliknie odpowiedni przycisk. –

+1

@Hans Passant: To pytanie jest podyktowane moją wątpliwością co do skrzynki z wiadomościami, to dlaczego zostałem zapytany "Czy to możliwe, czy nie?" –

+3

Zasadniczo zgadzam się z Hans Passant. Myślę, że skrzynki wiadomości powinny mieć spójny wygląd i styl. Ale co to znaczy w dzisiejszych czasach? Istnieje przecież wiele programów z bardziej rozbudowanymi skrzynkami komunikacyjnymi, a nie tylko z Okienkami. Sądzę, że większość użytkowników nie byłaby zaskoczona, gdyby rzeczy takie jak styl przycisku i jego przód różniły się nieco w skrzynkach wiadomości w różnych programach. – matsolof

Odpowiedz

46

Nie można zmienić styl domyślny MessageBox jak to jest zależne od aktualnego systemu operacyjnego Windows tematu, jednak można łatwo tworzyć własne MessageBox. Wystarczy dodać nową formę (tj MyNewMessageBox) do projektu z tymi ustawieniami:

FormBorderStyle FixedToolWindow 
ShowInTaskBar  False 
StartPosition  CenterScreen 

aby pokazać je wykorzystywać myNewMessageBoxInstance.ShowDialog();. Dodaj do formularza etykietę i przyciski, takie jak OK i Anuluj, i odpowiednio ustaw odpowiednie właściwości DialogRead, np. Dodaj przycisk do MyNewMessageBox i nazwij go btnOK. Ustaw właściwość DialogResult w oknie właściwości na DialogResult.OK. Gdy ten przycisk jest wciśnięty to zwróci OK wynik:

MyNewMessageBox myNewMessageBoxInstance = new MyNewMessageBox(); 
DialogResult result = myNewMessageBoxInstance.ShowDialog(); 
if (result == DialogResult.OK) 
{ 
    // etc 
} 

Byłoby wskazane, aby dodać swoją własną audycję metodę, która pobiera tekst i inne opcje wymagać:

public DialogResult Show(string text, Color foreColour) 
{ 
    lblText.Text = text; 
    lblText.ForeColor = foreColour; 
    return this.ShowDialog(); 
} 
11

MessageBox::Show używa funkcji z user32.dll, a jej styl jest zależna od systemu Windows, więc nie można zmienić go tak, trzeba utworzyć własną postać

4

Oto kod potrzebny do tworzenia własnych komunikat:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace MyStuff 
{ 
    public class MyLabel : Label 
    { 
     public static Label Set(string Text = "", Font Font = null, Color ForeColor = new Color(), Color BackColor = new Color()) 
     { 
      Label l = new Label(); 
      l.Text = Text; 
      l.Font = (Font == null) ? new Font("Calibri", 12) : Font; 
      l.ForeColor = (ForeColor == new Color()) ? Color.Black : ForeColor; 
      l.BackColor = (BackColor == new Color()) ? SystemColors.Control : BackColor; 
      l.AutoSize = true; 
      return l; 
     } 
    } 
    public class MyButton : Button 
    { 
     public static Button Set(string Text = "", int Width = 102, int Height = 30, Font Font = null, Color ForeColor = new Color(), Color BackColor = new Color()) 
     { 
      Button b = new Button(); 
      b.Text = Text; 
      b.Width = Width; 
      b.Height = Height; 
      b.Font = (Font == null) ? new Font("Calibri", 12) : Font; 
      b.ForeColor = (ForeColor == new Color()) ? Color.Black : ForeColor; 
      b.BackColor = (BackColor == new Color()) ? SystemColors.Control : BackColor; 
      b.UseVisualStyleBackColor = (b.BackColor == SystemColors.Control); 
      return b; 
     } 
    } 
    public class MyImage : PictureBox 
    { 
     public static PictureBox Set(string ImagePath = null, int Width = 60, int Height = 60) 
     { 
      PictureBox i = new PictureBox(); 
      if (ImagePath != null) 
      { 
       i.BackgroundImageLayout = ImageLayout.Zoom; 
       i.Location = new Point(9, 9); 
       i.Margin = new Padding(3, 3, 2, 3); 
       i.Size = new Size(Width, Height); 
       i.TabStop = false; 
       i.Visible = true; 
       i.BackgroundImage = Image.FromFile(ImagePath); 
      } 
      else 
      { 
       i.Visible = true; 
       i.Size = new Size(0, 0); 
      } 
      return i; 
     } 
    } 
    public partial class MyMessageBox : Form 
    { 
     private MyMessageBox() 
     { 
      this.panText = new FlowLayoutPanel(); 
      this.panButtons = new FlowLayoutPanel(); 
      this.SuspendLayout(); 
      // 
      // panText 
      // 
      this.panText.Parent = this; 
      this.panText.AutoScroll = true; 
      this.panText.AutoSize = true; 
      this.panText.AutoSizeMode = AutoSizeMode.GrowAndShrink; 
      //this.panText.Location = new Point(90, 90); 
      this.panText.Margin = new Padding(0); 
      this.panText.MaximumSize = new Size(500, 300); 
      this.panText.MinimumSize = new Size(108, 50); 
      this.panText.Size = new Size(108, 50); 
      // 
      // panButtons 
      // 
      this.panButtons.AutoSize = true; 
      this.panButtons.AutoSizeMode = AutoSizeMode.GrowAndShrink; 
      this.panButtons.FlowDirection = FlowDirection.RightToLeft; 
      this.panButtons.Location = new Point(89, 89); 
      this.panButtons.Margin = new Padding(0); 
      this.panButtons.MaximumSize = new Size(580, 150); 
      this.panButtons.MinimumSize = new Size(108, 0); 
      this.panButtons.Size = new Size(108, 35); 
      // 
      // MyMessageBox 
      // 
      this.AutoScaleDimensions = new SizeF(8F, 19F); 
      this.AutoScaleMode = AutoScaleMode.Font; 
      this.ClientSize = new Size(206, 133); 
      this.Controls.Add(this.panButtons); 
      this.Controls.Add(this.panText); 
      this.Font = new Font("Calibri", 12F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0))); 
      this.FormBorderStyle = FormBorderStyle.FixedSingle; 
      this.Margin = new Padding(4); 
      this.MaximizeBox = false; 
      this.MinimizeBox = false; 
      this.MinimumSize = new Size(168, 132); 
      this.Name = "MyMessageBox"; 
      this.ShowIcon = false; 
      this.ShowInTaskbar = false; 
      this.StartPosition = FormStartPosition.CenterScreen; 
      this.ResumeLayout(false); 
      this.PerformLayout(); 
     } 
     public static string Show(Label Label, string Title = "", List<Button> Buttons = null, PictureBox Image = null) 
     { 
      List<Label> Labels = new List<Label>(); 
      Labels.Add(Label); 
      return Show(Labels, Title, Buttons, Image); 
     } 
     public static string Show(string Label, string Title = "", List<Button> Buttons = null, PictureBox Image = null) 
     { 
      List<Label> Labels = new List<Label>(); 
      Labels.Add(MyLabel.Set(Label)); 
      return Show(Labels, Title, Buttons, Image); 
     } 
     public static string Show(List<Label> Labels = null, string Title = "", List<Button> Buttons = null, PictureBox Image = null) 
     { 
      if (Labels == null) Labels = new List<Label>(); 
      if (Labels.Count == 0) Labels.Add(MyLabel.Set("")); 
      if (Buttons == null) Buttons = new List<Button>(); 
      if (Buttons.Count == 0) Buttons.Add(MyButton.Set("OK")); 
      List<Button> buttons = new List<Button>(Buttons); 
      buttons.Reverse(); 

      int ImageWidth = 0; 
      int ImageHeight = 0; 
      int LabelWidth = 0; 
      int LabelHeight = 0; 
      int ButtonWidth = 0; 
      int ButtonHeight = 0; 
      int TotalWidth = 0; 
      int TotalHeight = 0; 

      MyMessageBox mb = new MyMessageBox(); 

      mb.Text = Title; 

      //Image 
      if (Image != null) 
      { 
       mb.Controls.Add(Image); 
       Image.MaximumSize = new Size(150, 300); 
       ImageWidth = Image.Width + Image.Margin.Horizontal; 
       ImageHeight = Image.Height + Image.Margin.Vertical; 
      } 

      //Labels 
      List<int> il = new List<int>(); 
      mb.panText.Location = new Point(9 + ImageWidth, 9); 
      foreach (Label l in Labels) 
      { 
       mb.panText.Controls.Add(l); 
       l.Location = new Point(200, 50); 
       l.MaximumSize = new Size(480, 2000); 
       il.Add(l.Width); 
      } 
      int mw = Labels.Max(x => x.Width); 
      il.ToString(); 
      Labels.ForEach(l => l.MinimumSize = new Size(Labels.Max(x => x.Width), 1)); 
      mb.panText.Height = Labels.Sum(l => l.Height); 
      mb.panText.MinimumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), ImageHeight); 
      mb.panText.MaximumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), 300); 
      LabelWidth = mb.panText.Width; 
      LabelHeight = mb.panText.Height; 

      //Buttons 
      foreach (Button b in buttons) 
      { 
       mb.panButtons.Controls.Add(b); 
       b.Location = new Point(3, 3); 
       b.TabIndex = Buttons.FindIndex(i => i.Text == b.Text); 
       b.Click += new EventHandler(mb.Button_Click); 
      } 
      ButtonWidth = mb.panButtons.Width; 
      ButtonHeight = mb.panButtons.Height; 

      //Set Widths 
      if (ButtonWidth > ImageWidth + LabelWidth) 
      { 
       Labels.ForEach(l => l.MinimumSize = new Size(ButtonWidth - ImageWidth - mb.ScrollBarWidth(Labels), 1)); 
       mb.panText.Height = Labels.Sum(l => l.Height); 
       mb.panText.MinimumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), ImageHeight); 
       mb.panText.MaximumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), 300); 
       LabelWidth = mb.panText.Width; 
       LabelHeight = mb.panText.Height; 
      } 
      TotalWidth = ImageWidth + LabelWidth; 

      //Set Height 
      TotalHeight = LabelHeight + ButtonHeight; 

      mb.panButtons.Location = new Point(TotalWidth - ButtonWidth + 9, mb.panText.Location.Y + mb.panText.Height); 

      mb.Size = new Size(TotalWidth + 25, TotalHeight + 47); 
      mb.ShowDialog(); 
      return mb.Result; 
     } 

     private FlowLayoutPanel panText; 
     private FlowLayoutPanel panButtons; 
     private int ScrollBarWidth(List<Label> Labels) 
     { 
      return (Labels.Sum(l => l.Height) > 300) ? 23 : 6; 
     } 

     private void Button_Click(object sender, EventArgs e) 
     { 
      Result = ((Button)sender).Text; 
      Close(); 
     } 

     private string Result = ""; 
    } 
} 
4

Dodaj winform do projektu (nazwałem go frmShowMessage) i umieścić ten kontroluje na nim:

1. Panel  (pnlShowMessage) 
2. Label  (lblMessageText) 
3. PictureBox (pictureBox1) 
4. ImageList (imageList1) 

Wymień swoje nowe kody formularza poniżej:

using System; 
using System.Drawing; 
using System.Runtime.InteropServices; 
using System.Windows.Forms; 
using System.Drawing.Drawing2D; 

namespace CostumeMessageBox 
{ 
    public partial class frmShowMessage : Form 
    { 
     Button btnOk = new Button(); //Create object of Button. 
     Button btnCancel = new Button(); 
     Button btnNo = new Button(); 
     Button btnYes = new Button(); 
     public const int WM_NCLBUTTONDOWN = 0xA1; 
     public const int HT_CAPTION = 0x2; 

     [DllImportAttribute("user32.dll")] 
     public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam); 
     [DllImport("user32.dll")] 
     public static extern bool ReleaseCapture(); 
     public frmShowMessage() 
     { 
      InitializeComponent(); 
     } 

     /// <summary> 
     /// Here I am overriding Paint method of form object 
     /// and set it's background color as gradient. Here I am 
     /// using LinearGradientBrush class object to make gradient 
     /// color which comes in System.Drawing.Drawing2D namespace. 
     /// </summary> 
     /// <param name="e"></param> 
     protected override void OnPaint(PaintEventArgs e) 
     { 
      base.OnPaint(e); 
      ControlPaint.DrawBorder(e.Graphics, ClientRectangle, 
            Color.DarkRed, 3, ButtonBorderStyle.Solid, 
            Color.DarkRed, 3, ButtonBorderStyle.Solid, 
            Color.DarkRed, 3, ButtonBorderStyle.Solid, 
            Color.DarkRed, 3, ButtonBorderStyle.Solid); 
      //Rectangle rect = this.ClientRectangle; 
      //LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Snow, Color.SeaShell, 60); //LightCyan Lavender LightGray 
      //e.Graphics.FillRectangle(brush, rect); 
      //base.OnPaint(e); 
     } 

     private void frmShowMessage_Load(object sender, EventArgs e) 
     { 
      btnOk.Text = "تایید"; //Here we set text of Button. 
      btnOk.DialogResult = DialogResult.OK; //Set DialogResult property of button. 
      btnOk.FlatStyle = FlatStyle.Popup; //Set flat appearence of button. 
      btnOk.BackColor = Color.Beige; 
      btnOk.FlatAppearance.BorderSize = 0; 

      btnCancel.Text = "انصراف"; 
      btnCancel.DialogResult = DialogResult.Cancel; 
      btnCancel.FlatStyle = FlatStyle.Popup; 
      btnCancel.BackColor = Color.Beige; 
      btnCancel.FlatAppearance.BorderSize = 0; 

      btnNo.Text = "خیر"; 
      btnNo.DialogResult = DialogResult.No; 
      btnNo.FlatStyle = FlatStyle.Popup; 
      btnNo.BackColor = Color.Beige; 
      btnNo.FlatAppearance.BorderSize = 0; 

      btnYes.Text = "بله"; 
      btnYes.DialogResult = DialogResult.Yes; 
      btnYes.FlatStyle = FlatStyle.Popup; 
      btnYes.BackColor = Color.Beige; 
      btnYes.FlatAppearance.BorderSize = 0; 
     } 


     /// <summary> 
     /// setMessage method is used to display message 
     /// on form and it's height adjust automatically. 
     /// I am displaying message in a Label control. 
     /// </summary> 
     /// <param name="messageText">Message which needs to be displayed to user.</param> 
     private void setMessage(string messageText) 
     { 
      int number = Math.Abs(messageText.Length/30); 
      if (number != 0) 
      { 
       lblMessageText.Height = lblRightBorder.Height = number*25; 
       Height = lblMessageText.Height; 
      } 

      lblMessageText.Text = messageText; 
     } 

     /// <summary> 
     /// This method is used to add button on message box. 
     /// </summary> 
     /// <param name="MessageButton">MessageButton is type of enumMessageButton 
     /// through which I get type of button which needs to be displayed.</param> 
     private void addButton(enumMessageButton MessageButton) 
     { 
      switch (MessageButton) 
      { 
       case enumMessageButton.OK: 
        { 
         //If type of enumButton is OK then we add OK button only. 
         btnOk.SetBounds(pnlShowMessage.ClientSize.Width - 80, 5, 75, 25); // Set bounds of button. 
         pnlShowMessage.Controls.Add(btnOk); //Finally Add button control on panel. 
        } 
        break; 
       case enumMessageButton.OKCancel: 
        { 
         btnOk.SetBounds((pnlShowMessage.ClientSize.Width - 70), 5, 65, 25); 
         pnlShowMessage.Controls.Add(btnOk); 

         btnCancel.SetBounds((pnlShowMessage.ClientSize.Width - (btnOk.ClientSize.Width + 5 + 80)), 5, 75, 25); 
         pnlShowMessage.Controls.Add(btnCancel); 

        } 
        break; 
       case enumMessageButton.YesNo: 
        { 

         btnNo.SetBounds((pnlShowMessage.ClientSize.Width - 70), 5, 65, 25); 
         pnlShowMessage.Controls.Add(btnNo); 

         btnYes.SetBounds((pnlShowMessage.ClientSize.Width - (btnNo.ClientSize.Width + 5 + 80)), 5, 75, 25); 
         pnlShowMessage.Controls.Add(btnYes); 
        } 
        break; 
       case enumMessageButton.YesNoCancel: 
        { 
         btnCancel.SetBounds((pnlShowMessage.ClientSize.Width - 70), 5, 65, 25); 
         pnlShowMessage.Controls.Add(btnCancel); 

         btnNo.SetBounds((pnlShowMessage.ClientSize.Width - (btnCancel.ClientSize.Width + 5 + 80)), 5, 75, 25); 
         pnlShowMessage.Controls.Add(btnNo); 

         btnYes.SetBounds((pnlShowMessage.ClientSize.Width - (btnCancel.ClientSize.Width + btnNo.ClientSize.Width + 10 + 80)), 5, 75, 25); 
         pnlShowMessage.Controls.Add(btnYes); 
        } 
        break; 
      } 
     } 

     /// <summary> 
     /// We can use this method to add image on message box. 
     /// I had taken all images in ImageList control so that 
     /// I can eaily add images. Image is displayed in 
     /// PictureBox control. 
     /// </summary> 
     /// <param name="MessageIcon">Type of image to be displayed.</param> 
     private void addIconImage(enumMessageIcon MessageIcon) 
     { 
      switch (MessageIcon) 
      { 
       case enumMessageIcon.Error: 
        pictureBox1.Image = imageList1.Images["Error"]; //Error is key name in imagelist control which uniqly identified images in ImageList control. 
        break; 
       case enumMessageIcon.Information: 
        pictureBox1.Image = imageList1.Images["Information"]; 
        break; 
       case enumMessageIcon.Question: 
        pictureBox1.Image = imageList1.Images["Question"]; 
        break; 
       case enumMessageIcon.Warning: 
        pictureBox1.Image = imageList1.Images["Warning"]; 
        break; 
      } 
     } 

     #region Overloaded Show message to display message box. 

     /// <summary> 
     /// Show method is overloaded which is used to display message 
     /// and this is static method so that we don't need to create 
     /// object of this class to call this method. 
     /// </summary> 
     /// <param name="messageText"></param> 
     internal static DialogResult Show(string messageText) 
     { 
      frmShowMessage frmMessage = new frmShowMessage(); 
      frmMessage.setMessage(messageText); 
      frmMessage.addIconImage(enumMessageIcon.Information); 
      frmMessage.addButton(enumMessageButton.OK); 
      frmMessage.ShowDialog(); 
      return frmMessage.DialogResult; 
     } 

     internal static DialogResult Show(string messageText, string messageTitle) 
     { 
      frmShowMessage frmMessage = new frmShowMessage(); 
      frmMessage.Text = messageTitle; 
      frmMessage.setMessage(messageText); 
      frmMessage.addIconImage(enumMessageIcon.Information); 
      frmMessage.addButton(enumMessageButton.OK); 
      frmMessage.ShowDialog(); 
      return frmMessage.DialogResult; 
     } 

     internal static DialogResult Show(string messageText, string messageTitle, enumMessageIcon messageIcon, 
              enumMessageButton messageButton) 
     { 
      frmShowMessage frmMessage = new frmShowMessage(); 
      frmMessage.setMessage(messageText); 
      frmMessage.Text = messageTitle; 
      frmMessage.addIconImage(messageIcon); 
      frmMessage.addButton(messageButton); 
      frmMessage.ShowDialog(); 
      return frmMessage.DialogResult; 
     } 

     #endregion 


     private void frmShowMessage_MouseDown(object sender, MouseEventArgs e) 
     { 
      if (e.Button != MouseButtons.Left) return; 
      ReleaseCapture(); 
      SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0); 

     } 

    } 

    #region constant defiend in form of enumration which is used in showMessage class. 

    internal enum enumMessageIcon 
    { 
     Error, 
     Warning, 
     Information, 
     Question, 
    } 

    internal enum enumMessageButton 
    { 
     OK, 
     YesNo, 
     YesNoCancel, 
     OKCancel 
    } 

    #endregion 
} 

Teraz można zadzwonić Twój Customized MessageBox w Twoim projekcie takim jak ten:

private void btnQuestion_Click(object sender, EventArgs e) 
    { 
     frmShowMessage.Show(rch.Text, 
      "Message Text", enumMessageIcon.Question, enumMessageButton.YesNoCancel); 
    } 

    private void btnInformation_Click(object sender, EventArgs e) 
    { 
     frmShowMessage.Show(rch.Text, 
      "Message Text", enumMessageIcon.Information, enumMessageButton.OKCancel); 

    } 

    private void btnError_Click(object sender, EventArgs e) 
    { 
     frmShowMessage.Show(rch.Text, 
      "Message Text", enumMessageIcon.Error, enumMessageButton.OK); 
    } 

    private void btnWarning_Click(object sender, EventArgs e) 
    { 
     frmShowMessage.Show(rch.Text, 
      "Message Text", enumMessageIcon.Warning, enumMessageButton.YesNo); 

    } 

Zapomniałem linku, który z tego się nauczyłem.

+0

Brakuje częściowej klasy formularza zawierającej funkcję 'InitializeComponent()'. Jest to dobry przykład, ale nie nadaje się do natychmiastowej implementacji. – Nyerguds

+0

@Nyerguds Założono, że użytkownik o tym wie. I nie miało być kompletne w części formy. –