c# MessageBox di MahApps che utilizzano MVVM




wpf caliburn.micro (3)

Domanda semplice per i Merry Men di MahApps. Ho implementato un'applicazione utilizzando i tuoi fantastici controlli in stile metro utilizzando Caliburn.Micro per il materiale MVVM. Le nuove finestre di dialogo dei messaggi sembrano grandiose, ma al momento non c'è un modo chiaro per avviare queste finestre di dialogo senza scrivere il mio wrapper (che non sono contrario). Tuttavia, è stato fatto o c'è qualcosa che mi manca in modo da poter richiamare una finestra di messaggio da un modello di visualizzazione senza problemi?

Grazie per il tuo tempo.


Answer #1

Ho creato un wrapper per chiamare la finestra di dialogo del messaggio MahApps.Metro, perché stavo avendo lo stesso problema con il mio progetto MVVM. Ho dovuto creare un elenco di finestre aperte, che la prima finestra sarà sempre la mia MainWindow.

Ecco il mio codice DialogService :

public async Task<MessageDialogResult> ShowMessage(string message, MessageDialogStyle dialogStyle)
{
    var metroWindow = (_openedViews.First() as MetroWindow);
    metroWindow.MetroDialogOptions.ColorScheme = MetroDialogColorScheme.Accented;

    return await metroWindow.ShowMessageAsync("MY TITLE", message, dialogStyle, metroWindow.MetroDialogOptions);
}

Questo codice può essere utilizzato per mostrare finestre di dialogo con o senza risultato. Puoi notare che il suo ritorno è un Task<MessageDialogResult> , quindi se vuoi ottenere il risultato, puoi farlo proprio sul tuo ViewModel:

MessageDialogResult result = await _dialog.ShowMessage("SOME MESSAGE HERE", MessageDialogStyle.AffirmativeAndNegative).ConfigureAwait(false);

if (result == MessageDialogResult.Affirmative)
{
    //Do something
}

A proposito, se il metodo che chiama ShowMessage() bisogno di un risultato, DEVI mettere async sul compito, altrimenti non funzionerà. (se vuoi mostrare solo una finestra di dialogo, non è necessario).

Il mio progetto utilizza Framework 4.0 e posso solo usare async/await causa del pacchetto che ho dovuto installare da NuGet. Puoi accedere a questo link per la documentazione MSDN di questo pacchetto e puoi scaricare il pacchetto qui .

Spero che abbia risolto il tuo problema.

MODIFICARE:

Ho implementato un metodo sul mio DialogService per aprire qualsiasi finestra da qualsiasi ViewModel. Questo metodo utilizza il framework Microsoft Unity per creare un'istanza del mio oggetto, quindi chiamo Show() per aprirlo. Prima di una chiamata Show() , aggiungo questa finestra in un elenco.

Vedi il mio codice:

public void ShowView<T>(params ParameterOverride[] parameter)
{
    var window = UnityServiceConfigurator.Instance.Container.Resolve<T>(parameter) as MetroWindow;

    if (window != null)
    {
        if (Application.Current.MainWindow != window)
        {
            window.Owner = Application.Current.MainWindow;
            var ownerMetroWindow = (window.Owner as MetroWindow);

            if (!ownerMetroWindow.IsOverlayVisible())
                ownerMetroWindow.ShowOverlayAsync();
        }

        if (!_openedViews.Contains(window))
            _openedViews.Add(window);

        window.Show();
    }
}

Ecco come chiamo dal mio ViewModel:

_dialog.ShowView<MyView>();

Se si dispone di una sola finestra sull'intero software, è possibile salvare il riferimento e utilizzarlo per mostrare ShowMessageAsync() senza la necessità di creare un elenco solo per utilizzare il primo. Come questo:

var metroWindow = (Application.Current.MainWindow as MetroWindow);

Answer #2

Se hai una sola istanza della tua finestra visualizzata, puoi provare qualcosa del genere:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Caliburn.Micro;
using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;

namespace Busyboy
{
    [Export(typeof(IShell))]
    class MainViewModel : PropertyChangedBase, IShell
    {
        public void StartPomodoro()
        {
            var mainview0 = System.Windows.Application.Current.Windows.OfType<MainView>().FirstOrDefault();
            mainview0.ShowInputAsync("New Pomodoro", "Enter a name for new pomodoro session.");
        }
    }
}

E, dovresti avere un modo per identificare ogni finestra in modo da poter filtrare le finestre. Si prega di notare l'importazione "Metro.Controls.Dialogs" che contiene le estensioni.


Answer #3

A partire da 1.1.3-ALPHA * (per diventare 1.2.0) MahApps fornisce un aiuto per avviare i dialoghi da una VM, che funziona in una configurazione a finestre multiple:

1) Usa una proprietà allegata nella tua Finestra per registrare il tuo modello di vista con il sottosistema di dialogo.

Supponendo che DataContext della tua vista sia impostato sul modello di visualizzazione da cui vuoi avviare la finestra di dialogo, aggiungi questi attributi:

<Controls:MetroWindow 
    xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
    Dialog:DialogParticipation.Register="{Binding}">

2) Grab / injject DialogCoordinator:

new MainWindowViewModel(DialogCoordinator.Instance);

3) Mostra la finestra di dialogo dal modello di visualizzazione. Usa "questo" come contesto in modo che MahApps possa sposare il tuo modello di visualizzazione alla finestra corretta:

_dialogCoordinator.ShowMessageAsync(this, "Message from VM", "MVVM based dialogs!")




mahapps.metro