James
James

Reputation: 4052

Custom WPF MessageBox isn't returning a result

I have followed a tutorial (here) about creating custom MessageBoxes using WPF. I have a slight problem though, as at present my custom box doesn't return a MessageBoxResult. I don't understand why this is the case.

Here is the xaml file PDSAMessageBoxView:

 <Window x:Class="Resources.PDSAMessageBoxView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    WindowStyle="None"
    AllowsTransparency="True"
    Background="Transparent"
    ResizeMode="NoResize"
    ShowInTaskbar="True"
    FontFamily="Segoe UI"
    WindowStartupLocation="CenterScreen"
    Height="300"
    Width="420"
     >
 <Border>
 <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
     <TextBlock Name="tbMessage"
     Text="Message goes here..."
     TextWrapping="Wrap" />
        <StackPanel Grid.Row="1"
                    >
            <Button Content="Yes"
                     x:Name="btnYes"
                     Click="btnYes_Click" />
            <Button Content="No"
                     x:Name="btnNo"
                     Click="btnNo_Click" />
            <Button Content="OK"
                     x:Name="btnOk"
                     Click="btnOk_Click" />
            <Button Content="Cancel"
                     x:Name="btnCancel"
                     Click="btnCancel_Click" />
        </StackPanel>
    </Grid>
</Border>
</Window>

And here is the corresponding PDSAMessageBoxView.xaml.cs file:

public partial class PDSAMessageBoxView : Window
{
    public PDSAMessageBoxView()
    {
        InitializeComponent();
    }

    public static MessageBoxResult Show(string message)
    {
        return Show(message, string.Empty, MessageBoxButton.OK);
    }

    public static MessageBoxResult Show(string message,
      string caption)
    {
        return Show(message, caption, MessageBoxButton.OK);
    }

    public static MessageBoxResult Show(string message,
      string caption, MessageBoxButton buttons)
    {
        MessageBoxResult result = MessageBoxResult.None;
        PDSAMessageBoxView dialog = new PDSAMessageBoxView();

        dialog.Title = caption;
        dialog.tbMessage.Text = message;
        dialog.Buttons = buttons;
        // If just an OK button, allow the user to just 
        // move away from the dialog
        if (buttons == MessageBoxButton.OK)
            dialog.Show();
        else
        {
            dialog.ShowDialog();
            result = dialog.Result;
        }

        return result;
    }

    


    public MessageBoxButton Buttons { get; set; }

    public MessageBoxResult Result { get; set; }

    private void btnYes_Click(object sender, RoutedEventArgs e)
    {

    }

    private void btnNo_Click(object sender, RoutedEventArgs e)
    {

    }

    private void btnOk_Click(object sender, RoutedEventArgs e)
    {

    }

    private void btnCancel_Click(object sender, RoutedEventArgs e)
    {

    }
}

Finally the code is called like this:

MessageBoxResult result = Resources.PDSAMessageBoxView.Show("Are you sure you want to exit?", "Confirm Shutdown",
            System.Windows.MessageBoxButton.YesNo);

The result that is returned is always None. And also the buttons displayed are always yes, no, cancel and ok, when they should be only Yes and No.

If someone could point me in the right direction I'd be really grateful.

Upvotes: 1

Views: 1428

Answers (1)

BendEg
BendEg

Reputation: 21088

To:

The result that is returned is always None. And also the buttons displayed are always yes, no, cancel and ok, when they should be only Yes and No.

You simple forget to implement this function. You have to hide and show the buttons when this (public MessageBoxButton Buttons { get; set; }) property changed.

The next thing is, you forget to set the result in your button-click methods::

 private void btnYes_Click(object sender, RoutedEventArgs e)
    {

    }

    private void btnNo_Click(object sender, RoutedEventArgs e)
    {

    }

    private void btnOk_Click(object sender, RoutedEventArgs e)
    {

    }

Your are not finished implementing every thing, thats all.

Here is an correct implementation:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MessageBoxHelp
{
    public partial class PDSAMessageBoxView : Window
    {
        private MessageBoxButton buttons;

        public PDSAMessageBoxView()
        {
            InitializeComponent();
        }

        public static MessageBoxResult Show(string message)
        {
            return Show(message, string.Empty, MessageBoxButton.OK);
        }

        public static MessageBoxResult Show(string message,
          string caption)
        {
            return Show(message, caption, MessageBoxButton.OK);
        }

        public static MessageBoxResult Show(string message,
          string caption, MessageBoxButton buttons)
        {
            MessageBoxResult result = MessageBoxResult.None;
            PDSAMessageBoxView dialog = new PDSAMessageBoxView();

            dialog.Title = caption;
            dialog.tbMessage.Text = message;
            dialog.Buttons = buttons;
            // If just an OK button, allow the user to just 
            // move away from the dialog
            if (buttons == MessageBoxButton.OK)
                dialog.Show();
            else
            {
                dialog.ShowDialog();
                result = dialog.Result;
            }

            return result;
        }




        public MessageBoxButton Buttons
        {
            get
            {
                return buttons;
            }

            set
            {
                buttons = value;

                btnCancel.Visibility = Visibility.Collapsed;
                btnOk.Visibility = Visibility.Collapsed;
                btnYes.Visibility = Visibility.Collapsed;
                btnNo.Visibility = Visibility.Collapsed;

                switch (buttons)
                {
                    case MessageBoxButton.OK:
                        btnOk.Visibility = Visibility.Visible;
                        break;
                    case MessageBoxButton.OKCancel:
                        btnCancel.Visibility = Visibility.Visible;
                        btnOk.Visibility = Visibility.Visible;
                        break;

                    case MessageBoxButton.YesNo:
                        btnYes.Visibility = Visibility.Visible;
                        btnNo.Visibility = Visibility.Visible;
                        break;

                    case MessageBoxButton.YesNoCancel:
                        btnCancel.Visibility = Visibility.Visible;
                        break;
                }
            }
        }

        public MessageBoxResult Result { get; set; }

        private void btnYes_Click(object sender, RoutedEventArgs e)
        {
            Result = MessageBoxResult.Yes;
            this.Close();
        }

        private void btnNo_Click(object sender, RoutedEventArgs e)
        {
            Result = MessageBoxResult.No;
            this.Close();
        }

        private void btnOk_Click(object sender, RoutedEventArgs e)
        {
            Result = MessageBoxResult.OK;
            this.Close();
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            Result = MessageBoxResult.Cancel;
            this.Close();
        }
    }
}

I have changed your namespace to MessageBoxHelp, becuase Resource was a bad choise in my case.

Upvotes: 5

Related Questions