locked
Message Dialog in windows store apps (C#) using MVVM RRS feed

  • Question

  • Hello everybody !!!

    Somebody has an example of code that using Message DIalog in a Windows store app in c# using MVVM?

    If yes, could you please write it?

    Thanx very much

    Tuesday, September 10, 2013 3:34 PM

Answers

  • Yes, you need a command factory method which has an execute action signature that matches the method being called. i.e. one that returns a Task and understands this is actually an async action. You should perhaps create a new factory method and by convention perhaps end its name with Async. Do you follow this?
    Wednesday, September 11, 2013 5:16 PM

All replies

  • You have issue with creating MessageDialog in ViewModel?


    • Proposed as answer by Ben - GGT Tuesday, September 10, 2013 7:38 PM
    • Unproposed as answer by Ben - GGT Tuesday, September 10, 2013 7:38 PM
    Tuesday, September 10, 2013 7:15 PM
  • var dialog = new MessageDialog("I'm the View and I've been instructed to display this by the ViewModel.");
    await dialog.ShowAsync();
    I'd be happy with this.


     




    • Edited by Ben - GGT Tuesday, September 10, 2013 7:35 PM
    • Proposed as answer by Ben - GGT Tuesday, September 10, 2013 7:38 PM
    Tuesday, September 10, 2013 7:33 PM
  • In fact that's my code in my ViewModel:

    private async void EndVisit() { await LogService.PushLog(RegisterViewForLog.Accueil, MobiposteAction.Clic_Bouton, "Fin de la visite"); Stopwatch stopchrono = Chrono.Instance.GetChrono(); stopchrono.Stop(); Debug.WriteLine("Le temps écoulé est : {0}", stopchrono.Elapsed); ViewService.Service.NavigationService.NavigateTo( ViewService.Service.GetView(Constant.WorkingOrderPage)); await LogService.WriteToFile(); }

    I need before calling the LogService.PushLog method create a Message DIalog in order to ask the user if he need to finish the visit.

    What do you think?


    • Edited by DiddyRennes Wednesday, September 11, 2013 10:22 AM
    Wednesday, September 11, 2013 10:20 AM
  • I've tried it doesn't work ... please have a look to my answer to Oleg.

    Thanx

    Wednesday, September 11, 2013 10:22 AM
  • Nothing is going to await the method EndVisit finishing as it returns void. So return a Task and in the caller to EndVisit await this method call.

    • Edited by Ben - GGT Wednesday, September 11, 2013 11:09 AM
    Wednesday, September 11, 2013 10:53 AM
  • In fact that's my code in my ViewModel:

    private async void EndVisit() {

    var dialog = new MessageDialog("Your text in message dialog");
    await dialog.ShowAsync();

    await LogService.PushLog(RegisterViewForLog.Accueil, MobiposteAction.Clic_Bouton, "Fin de la visite"); Stopwatch stopchrono = Chrono.Instance.GetChrono(); stopchrono.Stop(); Debug.WriteLine("Le temps écoulé est : {0}", stopchrono.Elapsed); ViewService.Service.NavigationService.NavigateTo( ViewService.Service.GetView(Constant.WorkingOrderPage)); await LogService.WriteToFile(); }

    I need before calling the LogService.PushLog method create a Message DIalog in order to ask the user if he need to finish the visit.

    What do you think?


    Is it work for you?
    Wednesday, September 11, 2013 11:21 AM
  • NO I have this error message to the error list :

    Error 1 'await' requires that the type 'Windows.Foundation.IAsyncOperation<Windows.UI.Popups.IUICommand>' have a suitable GetAwaiter method. Are you missing a using directive for

    Wednesday, September 11, 2013 12:02 PM
  • Any sample please?
    Wednesday, September 11, 2013 12:12 PM
  • 1. To the original question, as above:

    var dialog = new MessageDialog("I'm the View and I've been instructed to display this by the ViewModel.");
    await dialog
    .ShowAsync();

    2. For the problem with the code as it stands, as above:

    Nothing is going to await the method EndVisit finishing as it returns void. So return a Task and in the caller to EndVisit await this method call.

    3. You need to ask a question and then respond too in the dialog.

    4. Worked example, which you could call from your implementation of ICommand if you were to use the MVVM pattern:

    private async Task GoToOtherPage()
            {
                bool result = false;
                if (!this.isDirty)
                {
                    var dialog = new MessageDialog("Do you wish to leave this page?");
                    dialog.Commands.Add(new UICommand("OK", new UICommandInvokedHandler((cmd) => result = true)));
                    dialog.Commands.Add(new UICommand("Cancel"));
                    IUICommand iuiCommand = await dialog.ShowAsync();
                }
                if (result)
                    //conditionally perform your logging & navigation here
            }

    Beyond the scope of the original question. But hope this helps.


    • Edited by Ben - GGT Wednesday, September 11, 2013 2:08 PM
    Wednesday, September 11, 2013 2:07 PM
  • Hello Ben, here is my complet code with your answer :

    /// <summary> /// Constructeur /// </summary> public DashboardViewModel() { //DisplayAppBar(true, true); GoBackCommand = CommandFactory.CreateCommand(GoToWorkingOrder); GoToHeritageCommand = CommandFactory.CreateCommand<TechnicalPost>(GoToHeritage); EndVisitCommand = CommandFactory.CreateCommand(EndVisit); }

    My COmmandFactory.CreateCommand Method :

            /// <summary>
            /// Create a nWorkingOrder parametrized command
            /// </summary>
            /// <param name="execute">Delegate called to the execution of the command</param>
            /// <param name="canExecute">Delegate called to know if the command can run</param>
            /// <returns>Bindable Command to a bouton / hyperlink</returns>
            public static ICommand CreateCommand(Action execute, Func<bool> canExecute)
            {
                Contract.Requires(execute != null);
                Contract.Requires(canExecute != null);
                return new DelegateCommand(execute, canExecute);
            }

    And the new code with your notice :

    /// <summary>
            /// Appelée lors de la fin de la visite
            /// </summary>
            private async Task EndVisit()
            {
                bool result = false;
             
                var dialog = new MessageDialog("Do you wish to leave this page?");
                dialog.Commands.Add(new UICommand("OK", new UICommandInvokedHandler((cmd) => result = true)));
                dialog.Commands.Add(new UICommand("Cancel"));
                IUICommand iuiCommand = await dialog.ShowAsync();
                if (result)
                {
                    await LogService.PushLog(RegisterViewForLog.Accueil, MobiposteAction.Clic_Bouton, "Fin de la visite");
                    Stopwatch stopchrono = Chrono.Instance.GetChrono();
                    stopchrono.Stop();
                    Debug.WriteLine("Le temps écoulé est : {0}", stopchrono.Elapsed);
                    ViewService.Service.NavigationService.NavigateTo(
                        ViewService.Service.GetView(Constant.WorkingOrderPage));
                    await LogService.WriteToFile();
                }
            }

    My ICommand declaration :

            /// <summary>
            /// Fin de la visite
            /// </summary>
            public ICommand EndVisitCommand { get; private set; }

    My CommandFactory Classe :

    namespace Commons.Navigation
    {
        /// <summary>
        /// Interface ICommandExtension
        /// </summary>
        public interface ICommandExtension
        {
            void RaiseCanExecuteChanged();
        }
        /// <summary>
        /// Class allowing to create commands from delegates
        /// </summary>
        public static class CommandFactory
        {
            /// <summary>
            ///Command with a typified parameter
            /// </summary>
            /// <typeparam name="T"></typeparam>
            public class DelegateCommand<T> : ICommand, ICommandExtension
            {
                private readonly Action<T> _execute;
                private readonly Func<T, bool> _canExecute;
                public DelegateCommand(Action<T> execute, Func<T, bool> canExecute)
                {
                    _execute = execute;
                    _canExecute = canExecute;
                }
                #region ICommand Members
                public bool CanExecute(object parameter)
                {
                    var value = (T)(parameter ?? default(T));
                    return _canExecute(value);
                }
                public void Execute(object parameter)
                {
                    var value = (T)(parameter ?? default(T));
                    _execute(value);
                }
                public event EventHandler CanExecuteChanged;
                #endregion ICommand Members
                public void RaiseCanExecuteChanged()
                {
                    EventHandler handler = this.CanExecuteChanged;
                    if (handler != null)
                        handler(this, EventArgs.Empty);
                }
            }
            /// <summary>
            /// Command without parameters
            /// </summary>
            public class DelegateCommand : ICommand, ICommandExtension
            {
                private readonly Action _execute;
                private readonly Func<bool> _canExecute;
                public DelegateCommand(Action execute, Func<bool> canExecute)
                {
                    _execute = execute;
                    _canExecute = canExecute;
                }
                #region ICommand Members
                public bool CanExecute(object parameter)
                {
                    return _canExecute();
                }
                public void Execute(object parameter)
                {
                    _execute();
                }
                public event EventHandler CanExecuteChanged;
                #endregion ICommand Members
                public void RaiseCanExecuteChanged()
                {
                    EventHandler handler = this.CanExecuteChanged;
                    if (handler != null)
                        handler(this, EventArgs.Empty);
                }
            }
            /// <summary>
            /// Create a nWorkingOrder parametrized command
            /// </summary>
            /// <param name="execute">Delegate called to the execution of the command</param>
            /// <param name="canExecute">Delegate called to know if the command can run</param>
            /// <returns>Bindable Command to a bouton / hyperlink</returns>
            public static ICommand CreateCommand(Action execute, Func<bool> canExecute)
            {
                Contract.Requires(execute != null);
                Contract.Requires(canExecute != null);
                return new DelegateCommand(execute, canExecute);
            }
            /// <summary>
            /// Create a nWorkingOrder parametrized command
            /// </summary>
            /// <param name="execute">Delegate called to the execution of the command</param>
            /// <param name="canExecute">Delegate called to know if the command can run</param>
            /// <returns>Bindable Command to a bouton / hyperlink</returns>
            public static ICommand CreateCommand(Action execute)
            {
                return CreateCommand(execute, () => true);
            }
            /// <summary>
            /// Create a parametrized command
            /// </summary>
            /// <typeparam name="T">Parameter Type</typeparam>
            /// <param name="execute">Delegate called to the execution</param>
            /// <param name="canExecute">Delegate called to know if the command is feasible</param>
            /// <returns>Bindable Command to a button</returns>
            public static ICommand CreateCommand<T>(Action<T> execute, Func<T, bool> canExecute)
            {
                Contract.Requires(execute != null);
                Contract.Requires(canExecute != null);
                return new DelegateCommand<T>(execute, canExecute);
            }
            /// <summary>
            /// Create a parametrized command
            /// </summary>
            /// <typeparam name="T">Parameter Type</typeparam>
            /// <param name="displayText"></param>
            /// <param name="execute">Delegate called to the execution</param>
            /// <returns>Bindable Command to a button</returns>
            public static ICommand CreateCommand<T>(Action<T> execute)
            {
                return CreateCommand(execute, o => true);
            }
        }
    }

    I have 2 errors messages :

    - Error 2 'System.Threading.Tasks.Task Moozorte.ViewModels.DashboardViewModel.EndVisit()' has the wrong return type C:\Users\Utilisateur\Desktop\ModernUIApplication\PRESENTATION_SOCLE\Application\Mozorte\ViewModels\DashboardViewModel.cs 76 60 Mozorte

    - Error 3 'await' requires that the type 'Windows.Foundation.IAsyncOperation<Windows.UI.Popups.IUICommand>' have a suitable GetAwaiter method. Are you missing a using directive for 'System'? C:\Users\Utilisateur\Desktop\ModernUIApplication\PRESENTATION_SOCLE\Application\Mozorte\ViewModels\DashboardViewModel.cs 124 37 Mozorte

    Any suggestions? Thanx by advanced




    • Edited by DiddyRennes Wednesday, September 11, 2013 2:55 PM
    Wednesday, September 11, 2013 2:37 PM
  • Yes, you need a command factory method which has an execute action signature that matches the method being called. i.e. one that returns a Task and understands this is actually an async action. You should perhaps create a new factory method and by convention perhaps end its name with Async. Do you follow this?
    Wednesday, September 11, 2013 5:16 PM