RadWindow.Confirm should offer access to the dialog Datacontext

6 posts, 1 answers
  1. Jonx
    Jonx avatar
    258 posts
    Member since:
    Jul 2012

    Posted 15 Aug 2011 Link to this post

    Hi,
    Inside a view model I have a delete command that gets the guid of the entity to delete.
    Then I ask the user to confirm he wants to delete the element.
    Then only, I delete the element.

    The problem is that the predefined dialogs do not offer a way to pass parameters...
    That means that when the dialog closes I have no way of accessing an eventual parameter that the caller would have passed.
    Here I would like in the Closed event to know the id of the element I asked confirmation for, before I delete it...

    To pass a parameter I had to create a new control to use its datacontext to pass extra values...
    Here is my code... Is there a better way?
    Would you be so kind and add Datacontext as a possible property for DialogParameters?

    Thanks a lot in advance,
    John.

    private void ExecuteDeleteCommand(object o)
            {
                DialogContentParameter parameter = new DialogContentParameter();
                parameter.Text = "Are you sure you want to delete that meeting?";
                parameter.DataContext = o;
     
                RadWindow.Confirm(new DialogParameters()
                {
                    Content = parameter,
                    Closed = this.OnDeleteRdvClosed,
                });
            }
     
            private void OnDeleteRdvClosed(object sender, WindowClosedEventArgs e)
            {
                RadWindow dlg = sender as RadWindow;
                DialogContentParameter parameter = (dlg.Content as RadConfirm).Content as DialogContentParameter;
     
                if (e.DialogResult.HasValue && e.DialogResult.Value == true)
                {
                    Guid guid = Guid.Empty;
                    if (Guid.TryParse(parameter.DataContext.ToString(), out guid))
                    {
                        Meeting meeting = this.view.FirstOrDefault(m => m.MeeID == guid);
                        if (meeting != null)
                        {
                            Remove(meeting);
                            SaveCommand.Execute(null);
                        }
                    }
                }
            }

  2. Answer
    Miroslav Nedyalkov
    Admin
    Miroslav Nedyalkov avatar
    1718 posts

    Posted 16 Aug 2011 Link to this post

    Hi John,

     Thank you for your suggestion. We were thinking about adding such feature, but we decided that it is not needed as you can use lambda expression as a Closed handler and you can use it to pass parameters in it. Please take a look at the following sample code:

    var currentValue = 10;
    RadWindow.Confirm(
    new DialogParameters
    {
    Content = String.Format("Are you sure you want to do this with {0}?", currentValue),
    Closed = (s, args) => RadWindow.Alert(String.Format("The value was {0} and the result is {1}.", currentValue, args.DialogResult)
    });

    Hope this helps.

    Regards,
    Miroslav Nedyalkov
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get now >>

  3. DevCraft banner
  4. Jonx
    Jonx avatar
    258 posts
    Member since:
    Jul 2012

    Posted 16 Aug 2011 Link to this post

    Excellent suggestion... I'm still not yet used to lambda expressions...
    Works like a charm...
    Thank you very much...
    John.
  5. Garry
    Garry avatar
    205 posts
    Member since:
    Nov 2010

    Posted 13 Sep 2011 Link to this post

    Miroslav,
    I am woking on something similar to this and I have opted to use the Telerik RadWindow instead of the MessageBox just so the styling can be consistent, however not being able to get the result is really a pain especially in a MVVM MEF situation.

    I am working on a Message/Dialog service for my App and I am stuck as to how to get a result back from the Prompt and Alert Windows. I looked at the solution you provided for John and it seems to be feasible if I am calling a RadWindow directly from the ViewModel, but doesn't seem to work well for a service.

    Here is my current code.

    MessageBoxService
    [Export(typeof(IMessageBoxService))]
        public class MessageBoxService : IMessageBoxService
        {
            /// <summary>
            /// Result of the prompt
            /// </summary>
            public string Result { get; set; }
     
            /// <summary>
            /// Shows a Prompt MessageBox
            /// </summary>
            /// <param name="message">Message to be displayed</param>
            /// <param name="caption">Title of prompt</param>
            /// <param name="okcontent">Content for the OK button</param>
            /// <param name="cancelcontent">Content for the Cancel button</param>
            public void Show(object message, object caption, object okcontent, object cancelcontent)
            {
                DialogParameters parameters = new DialogParameters { Content = message, Header = caption, CancelButtonContent = cancelcontent, OkButtonContent = okcontent, Theme = StyleManager.ApplicationTheme };
                RadWindow.Confirm(parameters, OnPromptClosed);
            }
            /// <summary>
            /// Shows a Prompt MessageBox
            /// </summary>
            /// <param name="message">Message to be displayed</param>
            /// <param name="caption">Title of prompt</param>
            public void Show(object message, object caption)
            {
                DialogParameters parameters = new DialogParameters { Content = message, Header = caption, Theme = StyleManager.ApplicationTheme };
                RadWindow.Confirm(parameters, OnPromptClosed);
            }
     
            private void OnPromptClosed(object sender, WindowClosedEventArgs e)
            {
                if (e.PromptResult != null && e.PromptResult != string.Empty)
                {
                    Result = e.PromptResult;
                }
            }

    ActionCommand to call it form the ViewModel
    OptionsCommand = new ActionCommand<object>(obj =>
     
    {
     
    this.alertBoxService.Show("Alert Text", "Caption Text", "Button Text");
     
      
     
    //Does not work as the RadWindow does not lock the Main Thread
     
    if (alertBoxService.Result == true)
     
    {
     
    //Do Something
     
    }
     
    });

    Any suggestions here?

    Thanks,
    Garry
  6. Garry
    Garry avatar
    205 posts
    Member since:
    Nov 2010

    Posted 14 Sep 2011 Link to this post

    OK after spending a little bit more time on this I believe I have a solution for the Alert and Confirm prompts. Hopefully this will help someone else. Please let me know what you think.

    IAlertBoxService 
    public interface IAlertBoxService
        {
            void Show(object message, object caption, object okcontent);
            void Show<TViewModel>(object message, object caption, object okcontent, TViewModel viewModel, Action<TViewModel> onDialogClose);
            void Show(object message, object caption);
            bool Result { get; set; }
        }

    AlertBoxService
    public bool Result { get; set; }
            /// <summary>
            /// Shows an Alert MessageBox
            /// </summary>
            /// <param name="message">Message to be displayed</param>
            /// <param name="caption">Title of prompt</param>
            /// <param name="okcontent">Content for the OK button</param>
            /// <param name="cancelcontent">Content for the Cancel button</param>
            public void Show(object message, object caption, object okcontent)
            {
               DialogParameters parameters = new DialogParameters { Content = message, Header = caption, OkButtonContent = okcontent, Theme = StyleManager.ApplicationTheme, Closed = OnClosed };
               RadWindow.Alert(parameters);
            }
     
            /// <summary>
            /// Shows an Alert MessageBox
            /// </summary>
            /// <param name="message">Message to be displayed</param>
            /// <param name="caption">Title of prompt</param>
            /// <param name="okcontent">Content for the OK button</param>
            /// <param name="cancelcontent">Content for the Cancel button</param>
            /// <param name="viewModel">ViewModel from which the service is called from</param>
            /// <param name="onDialogClose">Callback Action in order to return the value back to the calling viewmodel</param>
            public void Show<TViewModel>(object message, object caption, object okcontent, TViewModel viewModel, Action<TViewModel> onDialogClose)
            {
               DialogParameters parameters = new DialogParameters { Content = message, Header = caption, OkButtonContent = okcontent, Theme = StyleManager.ApplicationTheme};
                if (onDialogClose != null)
                {
                    parameters.Closed += OnClosed;
                    parameters.Closed += (sender, e) => onDialogClose(viewModel);
                }
                RadWindow.Alert(parameters);
            }
             
            /// <summary>
            /// Shows an Alert MessageBox
            /// </summary>
            /// <param name="message">Message to be displayed</param>
            /// <param name="caption">Title of prompt</param>
            public void Show(object message, object caption)
            {
                DialogParameters parameters = new DialogParameters { Content = message, Header = caption, Theme = StyleManager.ApplicationTheme, Closed = OnClosed };
                RadWindow.Alert(parameters);           
            }
     
            private void OnClosed(object sender, WindowClosedEventArgs e)
            {
                Result =  e.DialogResult ?? false;
                NotifyPropertyChanged("Result");
            }
     
            // Declare the PropertyChanged event
            public event PropertyChangedEventHandler PropertyChanged;
     
            // NotifyPropertyChanged will raise the PropertyChanged event passing the
            // source property that is being updated.
            public void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
     
        }

    IMessageBoxService
    public interface IMessageBoxService
       {
           void Show(object message, object caption, object okcontent, object cancelcontent);
           void Show<TViewModel>(object message, object caption, object okcontent, object cancelcontent, TViewModel viewModel, Action<TViewModel> onDialogClose);
           void Show(object message, object caption);
           bool Result { get; set; }
       }

    MessageBoxService
    [Export(typeof(IMessageBoxService))]
        public class MessageBoxService : IMessageBoxService
        {
            public bool Result { get; set; }
            /// <summary>
            /// Shows an Confirm MessageBox
            /// </summary>
            /// <param name="message">Message to be displayed</param>
            /// <param name="caption">Title of prompt</param>
            /// <param name="okcontent">Content for the OK button</param>
            /// <param name="cancelcontent">Content for the Cancel button</param>
            public void Show(object message, object caption, object okcontent, object cancelcontent)
            {
               DialogParameters parameters = new DialogParameters { Content = message, Header = caption, OkButtonContent = okcontent, Theme = StyleManager.ApplicationTheme, Closed = OnClosed };
               RadWindow.Confirm(parameters);
            }
     
            /// <summary>
            /// Shows an Confirm MessageBox
            /// </summary>
            /// <param name="message">Message to be displayed</param>
            /// <param name="caption">Title of prompt</param>
            /// <param name="okcontent">Content for the OK button</param>
            /// <param name="cancelcontent">Content for the Cancel button</param>
            /// <param name="viewModel">ViewModel from which the service is called from</param>
            /// <param name="onDialogClose">Callback Action in order to return the value back to the calling viewmodel</param>
            public void Show<TViewModel>(object message, object caption, object okcontent,object cancelcontent, TViewModel viewModel, Action<TViewModel> onDialogClose)
            {
               DialogParameters parameters = new DialogParameters { Content = message, Header = caption, OkButtonContent = okcontent, CancelButtonContent=cancelcontent, Theme = StyleManager.ApplicationTheme};
                if (onDialogClose != null)
                {
                    parameters.Closed += OnClosed;
                    parameters.Closed += (sender, e) => onDialogClose(viewModel);
                }
                RadWindow.Confirm(parameters);
            }
             
            /// <summary>
            /// Shows an Confirm MessageBox
            /// </summary>
            /// <param name="message">Message to be displayed</param>
            /// <param name="caption">Title of prompt</param>
            public void Show(object message, object caption)
            {
                DialogParameters parameters = new DialogParameters { Content = message, Header = caption, Theme = StyleManager.ApplicationTheme, Closed = OnClosed };
                RadWindow.Confirm(parameters);           
            }
     
            private void OnClosed(object sender, WindowClosedEventArgs e)
            {
                Result = e.DialogResult ?? false;
                NotifyPropertyChanged("Result");
            }
     
            // Declare the PropertyChanged event
            public event PropertyChangedEventHandler PropertyChanged;
     
            // NotifyPropertyChanged will raise the PropertyChanged event passing the
            // source property that is being updated.
            public void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }

    You can call these services anyway you wish, but here is an example calling the MessageBoxService from a ActionCommand.
    OptionsCommand = new ActionCommand<object>(obj =>
                                                                   {
                                                                       //Calls an Alert service to display an AlertBox and return the result
                                                                       this.messageBoxService.Show("Alert Text", "Caption Text","OK","Cancel",this,
                                                                           returnedViewModelInstance =>
                                                                           {
                                                                               bool result = messageBoxService.Result;
                                                                           });
                                                                   });

    and the AlertBoxService
    OptionsCommand = new ActionCommand<object>(obj =>
                                                                   {
                                                                       //Calls an Alert service to display an AlertBox and return the result
                                                                       this.alertBoxService.Show("Alert Text", "Caption Text","OK",this,
                                                                           returnedViewModelInstance =>
                                                                           {
                                                                               bool result = alertBoxService.Result;
                                                                           });
                                                                   });

    I know these two services look almost exactly the same except for the OK and Cancel buttons and I could easily consolidate these into one interface/class, but I like them seperated so I can modify either later on and it makes reuse for other peeps clearer on their purpose.

    Anyhow I hope this may help some others out there.

    Garry
  7. Miroslav Nedyalkov
    Admin
    Miroslav Nedyalkov avatar
    1718 posts

    Posted 17 Sep 2011 Link to this post

    Hi Garry,

     Thank you for your suggestion. As you noticed the RadWindow control is working in an asynchronous manner - it doesn't block the thread and it provides a callback to notify when the operation is finished. This is the advisable way for a web application UI to work. What you could do is to design your service also to work asynchronously.

    Best wishes,
    Miroslav Nedyalkov
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

Back to Top
DevCraft banner