14

I'm trying to make a custom message box with my controls.

public static partial class Msg : Form
{
    public static void show(string content, string description)
    {

    }
}

Actually I need to place some controls (a gridview) in this form and I have to apply my own theme for this window, so I don't want to use MessageBox. I want to call this from my other forms like

Msg.show(parameters);

I don't wish to create an object for this form.

I know I can't inherit from Form class because it isn't static. But I wonder how MessageBox is implemented, because it is static. It is being called like MessageBox.show("Some message!");

Now I'm getting an error because inheritance is not allowed:

Static class 'MyFormName' cannot derive from type 'System.Windows.Forms.Form'. Static classes must derive from object

Screenshot of my form

How MessageBox is implemented then?

Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
Sen Jacob
  • 3,384
  • 3
  • 35
  • 61
  • 3
    .NET's MessageBox is just a wrapper for the MessageBox that is part of Win32. You will need to create a Form object for your custom MessageBox. Possibly make it a singleton. Or just create a new Form, show it, and then dispose it each time `Msg.Show()` is called. – Matt Greer Aug 03 '11 at 20:25
  • 2
    `Msg` class doesn't have to be static for `show` to be static. – Joe Aug 03 '11 at 20:27

4 Answers4

26

Your form class needs not to be static. In fact, a static class cannot inherit at all.

Instead, create an internal form class that derives from Form and provide a public static helper method to show it.

This static method may be defined in a different class if you don't want the callers to even “know” about the underlying form.

/// <summary>
/// The form internally used by <see cref="CustomMessageBox"/> class.
/// </summary>
internal partial class CustomMessageForm : Form
{
    /// <summary>
    /// This constructor is required for designer support.
    /// </summary>
    public CustomMessageForm ()
    {
        InitializeComponent(); 
    } 

    public CustomMessageForm (string title, string description)
    {
        InitializeComponent(); 

        this.titleLabel.Text = title;
        this.descriptionLabel.Text = description;
    } 
}

/// <summary>
/// Your custom message box helper.
/// </summary>
public static class CustomMessageBox
{
    public static void Show (string title, string description)
    {
        // using construct ensures the resources are freed when form is closed
        using (var form = new CustomMessageForm (title, description)) {
            form.ShowDialog ();
        }
    }
}

Side note: as Jalal points out, you don't have to make a class static in order to have static methods in it. But I would still separate the “helper” class from the actual form so the callers cannot create the form with a constructor (unless they're in the same assembly of course).

Community
  • 1
  • 1
Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
  • Thanks for your quick reply.. I did the form.. Thank you Dan Abramov for a different Answer with internal class usage :) – Sen Jacob Aug 03 '11 at 20:58
  • yeah, by using this internal class, I could prevent calling constructors, It was a new concept for me... Thank you once again for explaining. – Sen Jacob Aug 03 '11 at 21:16
  • 1
    Yeah—but this only works when you define these classes in a separate assembly. Another option would be to declare the `Form` class *inside* the static helper and declare it `private` but you would lose the designer so I think this isn't worth it. – Dan Abramov Aug 03 '11 at 21:18
  • 1
    using (var form = new CustomMessageForm (title, description)) { form.ShowDialog ();} could you explain why you used var? .......... new CustomMessageForm (title, description).showDialog(); is this code has any problem to be a well programmed code? Sorry, I didn't got much chance to learn these concepts. I just want to learn these best practices – Sen Jacob Aug 03 '11 at 21:35
  • 1
    @BeediKumaraN: `var` lets the compiler infer the type for you so you don't have to write the name twice `CustomMessageForm form = new CustomMessageForm`. I suggest you [google this](http://google.com/search?q=var+c%23) first and also read [this thread](http://stackoverflow.com/questions/41479/use-of-var-keyword-in-c). Generally, please post a new question on its own instead of discussion in comments. – Dan Abramov Aug 03 '11 at 21:39
  • If I want to create two buttons in this custom message box (Ok, Cancel), how would I do to get what button was pressed to terminate the Message box ? I tried to return a DialogResult from the Show Method but it causes trouble with non-static member – TmZn Aug 29 '19 at 23:30
5

You don't need the class to be static. Just do something like:

public partial class Msg : Form
{
    public static void show(string content, string description)
    {
         Msg message = new Msg(...);
         message.show();
    }
}
Lior Ohana
  • 3,467
  • 4
  • 34
  • 49
2

You don't need to make the class static in order to call one of its methods statically — it's sufficient to declare the particular method as static.

public partial class DetailedMessageBox : Form
{
    public DetailedMessageBox()
    {
        InitializeComponent();
    }

    public static void ShowMessage(string content, string description)
    {
        DetailedMessageBox messageBox = new DetailedMessageBox();
        messageBox.ShowDialog();
    }
}

We are using messageBox.ShowDialog() to have the form being displayed as a modal window. You can display the message box using DetailedMessageBox.ShowMessage("Content", "Description");.

By the way, you should rethink your naming and stick to a consistent naming pattern. Msg and show are weak names that do no match the Naming Guidelines — you would definitely want to check those out!

Marius Schulz
  • 15,976
  • 12
  • 63
  • 97
-2

In a WPF project you can add a new window and call it MessageBoxCustom then inside C# the Void where you can find InitialiseComponent(); you add 2 properties and bind those properties to the textBlocks you should have created inside your XAML view Example:

public MessageBoxCustom(string Message, string Title)
{
    InitialiseComponent();//this comes first to load Front End
    textblock1.Text = Title;
    textblock2.Text = Message;
}

Just position your TextBlocks where you want them to be displayed in XAML


From your Main Window you can call that message box like this


private void Button_Click()
{
    MessageBoxCustom msg = new MessageBoxCustom("Your message here","Your title her");
    msg.ShowDialog();
}
onur
  • 374
  • 4
  • 19
TGB
  • 1