Vista/Seven Style Question Box

Diamonddrake 2 Tallied Votes 236 Views Share

A project I am working needed a question style message box, but I wanted that contemporary look of Vista and Seven. I set out to see how it was accomplished, turns out there are some special APIs that exist in Vista and Seven that don't exist in XP that accomplish that look. This isn't what I hoped for. I want an interface that looks contemporary even in XP.

So I decided to create a very simple messagebox type form that had the appearance of the vista/seven question dialogs, the simplest way possible. This is my result. it uses the multiline label control I already posted here, but I included all the code here for simplicity.

I wanted that windows forms MessageBox.Show() static simplicity. So I created a static class that creates an instance of the messagebox with overloaded constructors to make it simple.

its as easy as

if (QuestionBox.Show("Example Caption", "Example question?", "Example Description") == DialogResult.Yes)
                {
                    //do something
                }

best part is, all managed, no extra api calls, and it looks identical in XP, Vista, and windows 7

kvprajapati commented: Helpful! +11
cale.macdonald commented: Very clean, concise, well written +2
//2010 Rickey Ward Diamonddrake.com
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace DiamondDrake.Forms
{

    public class frmQuestionBox : Form
    {
        public frmQuestionBox()
        {
            InitializeComponent();
            this.Icon = SystemIcons.Question;
            pictureBox1.Image = SystemIcons.Question.ToBitmap();
        }

        public frmQuestionBox(string caption, string question)
            : this()
        {
            this.Text = caption;
            this.QuestionText = question;
            this.DescriptionText = string.Empty;
        }

        public frmQuestionBox(string caption, string question, Image Image24x24)
            : this()
        {
            this.Text = caption;
            this.QuestionText = question;
            this.DescriptionText = string.Empty;
            pictureBox1.Image = (Image)Image24x24.Clone();
        }

        public frmQuestionBox(string caption, string question, string description)
            : this()
        {
            this.Text = caption;
            this.QuestionText = question;
            this.DescriptionText = description;
        }

        public frmQuestionBox(string caption, string question, string description, Image Image24x24)
            : this()
        {
            this.Text = caption;
            this.QuestionText = question;
            this.DescriptionText = description;
            pictureBox1.Image = (Image)Image24x24.Clone();
        }

        public string QuestionText
        {
            get { return this.lblbx_question.Text; }
            set { this.lblbx_question.Text = value; }
        }

        public string DescriptionText
        {
            get { return this.lblbx_descripton.Text; }
            set { this.lblbx_descripton.Text = value; }
        }

        #region VSDesigner stuff

                /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.pnlButtons = new System.Windows.Forms.Panel();
            this.btnCancel = new System.Windows.Forms.Button();
            this.btnOK = new System.Windows.Forms.Button();
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            this.lblbx_question = new DiamondDrake.Controls.LabelBox();
            this.lblbx_descripton = new DiamondDrake.Controls.LabelBox();
            this.pnlButtons.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
            this.SuspendLayout();
            // 
            // pnlButtons
            // 
            this.pnlButtons.BackColor = System.Drawing.SystemColors.Control;
            this.pnlButtons.Controls.Add(this.btnCancel);
            this.pnlButtons.Controls.Add(this.btnOK);
            this.pnlButtons.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.pnlButtons.Location = new System.Drawing.Point(0, 105);
            this.pnlButtons.Name = "pnlButtons";
            this.pnlButtons.Size = new System.Drawing.Size(335, 39);
            this.pnlButtons.TabIndex = 0;
            // 
            // btnCancel
            // 
            this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.No;
            this.btnCancel.Location = new System.Drawing.Point(171, 8);
            this.btnCancel.Name = "btnCancel";
            this.btnCancel.Size = new System.Drawing.Size(75, 23);
            this.btnCancel.TabIndex = 1;
            this.btnCancel.Text = "No";
            this.btnCancel.UseVisualStyleBackColor = true;
            // 
            // btnOK
            // 
            this.btnOK.DialogResult = System.Windows.Forms.DialogResult.Yes;
            this.btnOK.Location = new System.Drawing.Point(252, 8);
            this.btnOK.Name = "btnOK";
            this.btnOK.Size = new System.Drawing.Size(75, 23);
            this.btnOK.TabIndex = 0;
            this.btnOK.Text = "Yes";
            this.btnOK.UseVisualStyleBackColor = true;
            // 
            // pictureBox1
            // 
            this.pictureBox1.Location = new System.Drawing.Point(12, 12);
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(48, 48);
            this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
            this.pictureBox1.TabIndex = 1;
            this.pictureBox1.TabStop = false;
            // 
            // lblbx_question
            // 
            this.lblbx_question.BackColor = System.Drawing.Color.Transparent;
            this.lblbx_question.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F);
            this.lblbx_question.ForeColor = System.Drawing.Color.Blue;
            this.lblbx_question.HorizontalAlignment = System.Drawing.StringAlignment.Near;
            this.lblbx_question.Location = new System.Drawing.Point(66, 12);
            this.lblbx_question.Name = "lblbx_question";
            this.lblbx_question.Size = new System.Drawing.Size(257, 48);
            this.lblbx_question.TabIndex = 2;
            this.lblbx_question.Text = "This is a sample question?";
            this.lblbx_question.VerticalAlignment = System.Drawing.StringAlignment.Center;
            // 
            // lblbx_descripton
            // 
            this.lblbx_descripton.BackColor = System.Drawing.Color.Transparent;
            this.lblbx_descripton.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lblbx_descripton.HorizontalAlignment = System.Drawing.StringAlignment.Near;
            this.lblbx_descripton.Location = new System.Drawing.Point(12, 66);
            this.lblbx_descripton.Name = "lblbx_descripton";
            this.lblbx_descripton.Size = new System.Drawing.Size(311, 33);
            this.lblbx_descripton.TabIndex = 3;
            this.lblbx_descripton.Text = "This is a sample description";
            this.lblbx_descripton.VerticalAlignment = System.Drawing.StringAlignment.Near;
            // 
            // frmQuestionBox
            // 
            this.AcceptButton = this.btnOK;
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.BackColor = System.Drawing.Color.White;
            this.CancelButton = this.btnCancel;
            this.ClientSize = new System.Drawing.Size(335, 144);
            this.Controls.Add(this.lblbx_descripton);
            this.Controls.Add(this.lblbx_question);
            this.Controls.Add(this.pictureBox1);
            this.Controls.Add(this.pnlButtons);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "frmQuestionBox";
            this.ShowInTaskbar = false;
            this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "frmQuestionBox";
            this.TopMost = true;
            this.pnlButtons.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Panel pnlButtons;
        private System.Windows.Forms.Button btnCancel;
        private System.Windows.Forms.Button btnOK;
        private System.Windows.Forms.PictureBox pictureBox1;
        private DiamondDrake.Controls.LabelBox lblbx_question;
        private DiamondDrake.Controls.LabelBox lblbx_descripton;

        #endregion


    }

    public static class QuestionBox
    {
        public static DialogResult Show(string caption, string question)
        {
            using (frmQuestionBox dialog = new frmQuestionBox(caption, question))
            {
                return dialog.ShowDialog();
            }    
        }

        public static DialogResult Show(string caption, string question, string description)
        {
            using (frmQuestionBox dialog = new frmQuestionBox(caption, question, description))
            {
                return dialog.ShowDialog();
            }
        }

        public static DialogResult Show(string caption, string question, string description, Image Image24x24)
        {
            using (frmQuestionBox dialog = new frmQuestionBox(caption, question, description, Image24x24))
            {
                return dialog.ShowDialog();
            }
        }

        public static DialogResult Show(string caption, string question, Image Image24x24)
        {
            using (frmQuestionBox dialog = new frmQuestionBox(caption, question, Image24x24))
            {
                return dialog.ShowDialog();
            }
        }
    }
}

namespace DiamondDrake.Controls
{
    public class LabelBox : Control
    {
        public LabelBox()
        {
            //Set up double buffering and a little extra.
            this.SetStyle(ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer |
            ControlStyles.AllPaintingInWmPaint | ControlStyles.SupportsTransparentBackColor,
            true);

            //set up some default values
            this.BackColor = Color.Transparent;
            _stringformat = new StringFormat();
            _stringformat.LineAlignment = StringAlignment.Near;
            _stringformat.Alignment = StringAlignment.Center;
            this.Font = new Font("Microsoft Sans Serif", 12F);
        }

        private StringFormat _stringformat;

        public StringAlignment VerticalAlignment
        {
            get { return _stringformat.LineAlignment; }
            set { _stringformat.LineAlignment = value; this.Invalidate(); }
        }
        public StringAlignment HorizontalAlignment
        {
            get { return _stringformat.Alignment; }
            set { _stringformat.Alignment = value; this.Invalidate(); }
        }
        

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            e.Graphics.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), this.ClientRectangle, _stringformat);
        }


    }
    
}

Dani AI

Generated

Nice, pragmatic work from — a small, fully managed dialog that gives a consistent Vista/7-style question box on XP, Vista and 7. A few focused changes make it behave more like the platform-native dialogs (modal/centering, font and DPI, resource/localization, and safe image handling) without losing the simplicity of the static QuestionBox.Show(...) API.

Make it modal to an owner instead of using TopMost; set StartPosition = CenterParent and add an overload that takes an IWin32Window so ShowDialog(owner) is used. That keeps modality and focus correct for multi-window apps and avoids always-on-top windows:

public static DialogResult Show(IWin32Window owner, string caption, string question)
{
    using (var dlg = new frmQuestionBox(caption, question))
        return dlg.ShowDialog(owner);
}

Use the system dialog font and localized button text. Set this.Font = SystemFonts.MessageBoxFont; and make the main instruction bold from that font so it matches native dialogs. Avoid hard-coded "Yes"/"No" strings — store button labels in resources (or mirror MessageBox wording) to support localization. When assigning bitmaps (Icon.ToBitmap/Clone), take ownership and dispose the old image explicitly so GDI handles are freed:

var old = pictureBox1.Image;
pictureBox1.Image = myIcon.ToBitmap();
old?.Dispose();

Be DPI-aware and size the label/form to the text. Call Application.EnableVisualStyles() early, pick an AutoScaleMode appropriate for your target runtime, and measure text with TextRenderer.MeasureText(..., TextFormatFlags.WordBreak) to compute wrapping and client size so long messages fit. If a true native Vista/7 look is required on Vista+ only, consider the Win32 Task Dialog API (TaskDialog/TaskDialogIndirect) and fall back to the custom form on older systems. (learn.microsoft.com)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.