1

So what I normally do to show a dialogue box and get a result in C# is,

    MessageBoxResult result = MessageBox.Show("Wrong username or password", "Invalid details", MessageBoxButton.OK, MessageBoxImage.Hand);
        string clear = "";
        if (result == MessageBoxResult.OK)
        {
            username.Text = clear;
            password.Password = clear;
        }

However I've always hated this standard look it gives so I decided to make my own dialogue box in wpf. Problem is I'm not too sure exactly how to return a dialogue result with that. It's just a simple box with an okay button that's supposed to clear the username and password fields.

Is there any way to do this?

Offer
  • 630
  • 2
  • 11
  • 28
  • I haven't done it in WPF, but I believe it's similar to WinForms, where you simply set a specific button's DialogResult property to OK. Then when you open the window with ShowDialog, it returns the result of whatever button you pressed. – Falgantil May 05 '14 at 14:50
  • There is a pretty great example on this site: No time to format it it for an answer. (this example is "Metro" style, but obviously you can change the view to whatever you want) http://www.sjurvarhaug.com/metro-style-messagebox-in-wpf – samuelesque May 05 '14 at 14:55
  • The 'Event Aggregator' is great for this sort of thing. You can also set a delegate in your dialog's view model to accomplish the same thing. – Gayot Fow May 05 '14 at 15:05

2 Answers2

1

I found this on another question here on SO (here Where is Button.DialogResult in WPF?)

 public class ButtonHelper
    {
        // Boilerplate code to register attached property "bool? DialogResult"
        public static bool? GetDialogResult(DependencyObject obj) 
        { 
            return (bool?)obj.GetValue(DialogResultProperty);
        }

        public static void SetDialogResult(DependencyObject obj, bool? value)
        {
            obj.SetValue(DialogResultProperty, value);
        }

        public static readonly DependencyProperty DialogResultProperty = 
            DependencyProperty.RegisterAttached(
            "DialogResult", typeof(bool?), typeof(ButtonHelper), new UIPropertyMetadata
        {
            PropertyChangedCallback = (obj, e) =>
            {
                // Implementation of DialogResult functionality
                var button = obj as Button;
                if (button == null)
                    throw new InvalidOperationException("Can only use ButtonHelper.DialogResult on a Button control");
                button.Click += (sender, e2) =>
                {
                    Window.GetWindow(button).DialogResult = GetDialogResult(button);
                };
            }
        });
    }

Then in the xaml for the "Ok" button

yourNameSpaceForTheButtonHelperClass:ButtonHelper.DialogResult="True"
Community
  • 1
  • 1
reggaeguitar
  • 1,795
  • 1
  • 27
  • 48
  • Hi, I'm at a loss as to what "yourNameSpaceForTheButtonHelperClass" means... Could you fill me in there? – Offer May 05 '14 at 17:40
  • This is the namespace that the ButtonHelper class is declared in. For example, in a solution I'm working on (called "NeoPrototype2") I declare this namespace in the dialog window xaml xmlns:view="clr-namespace:NeoPrototype2.View" because my ButtonHelper class is saved in the View folder of my solution, then the button xaml looks like this . Let me know if this is still unclear – reggaeguitar May 05 '14 at 17:49
  • Alright. I can safely confirm that this worked the way I wanted. Much gratitude. : ) – Offer May 05 '14 at 19:22
  • The next step is to use the MVVM Light Toolkit Messenger's class to send a message from the dialog ViewModel back to the main ViewModel, see this post http://stackoverflow.com/questions/16993433/mvvm-light-wpf-binding-multiple-instances-of-a-window-to-a-viewmodel/16994523 – reggaeguitar May 05 '14 at 19:46
0

Using the MVVM pattern, you could do this by exposing a DialogResult on the ViewModel your control is using. I highly recommend making an interface for this, thusly you can retrieve a result by casting to the interface regardless of the actual view model's type.

var control = new MyControl();
control.ShowDialog();  // Assuming your control is a Window
                       // - Otherwise, you'll have to wrap it in a window and event-bind to close it
result = (control.DataContext as IResultDialogVM).Result;

Alternatively, if you prefer to explicitly set your view models

var vm = new MyViewModel(question);
new MyControl { DataContext = vm }.ShowDialog();
result = vm.Result;
David
  • 10,458
  • 1
  • 28
  • 40
  • How do you set the result to true? – reggaeguitar May 05 '14 at 15:14
  • @reggaeguitar Event handlers in the ViewModel are the way to go if you're using MVVM. If you're not, the event handlers in Code Behind for the UserControl can also declare a Result Property and set it. – David May 05 '14 at 15:15