WPF MVVM Caricamento dati all'avvio

3

Sto costruendo una semplice GUI di dettagli master usando WPF / MVVM / Prism per alcuni dati provenienti da un servizio Restful.

Ho la finestra principale come vista principale con un modello di visualizzazione corrispondente.

Ho un controllo utente per mostrare i dati master e anche il suo modello di visualizzazione.

Ho aggiunto un'istanza del modello di visualizzazione dati master nel modello di visualizzazione principale. Non sono sicuro se questa è la migliore pratica. Quindi ho impostato il contesto dei dati della vista principale nel codice sottostante e del controllo utente utilizzando XAML della vista principale.

<Window x:Class="MyNamespace.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MyNamespace"
        xmlns:views="clr-namespace:MyNamespace.Views"
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding LoginAndLoadMasterDataCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <Grid>
        <views:MasterDataView DataContext="{Binding MasterData, Mode=OneWay}" />
    </Grid>
</Window>

Ora ho ottenuto due comandi uno per accedere al restful e questo è nel modello di visualizzazione principale, e un altro per caricare i dati master e questo è nel modello di visualizzazione figlio. Il caricamento dei dati potrebbe richiedere alcuni secondi.

Voglio sparare i due comandi in sequenza, e ho provato il comando composito Prism e ho anche provato ad aggiungere entrambi i comandi da attivare sul caricamento della vista, ma in entrambi i casi non mi consentono di controllare la sequenza di comandi in modo da caricare i dati vengono tentati prima che il login ritorni, il che fa sì che venga lanciata un'eccezione.

internal class MainViewModel : BindableBase
{
    private readonly ApiClient client = new ApiClient();

    public MasterDataViewModel MasterData { get; }

    public ICommand LoginAndLoadMasterDataCommand { get; }

    public  MainViewModel()
    {
        MasterData = new MasterDataViewModel(client);

        CompositeCommand loginCommand = new CompositeCommand(false);
        loginCommand.RegisterCommand(new DelegateCommand(async () => await client.Login()));
        loginCommand.RegisterCommand(MasterData.LoadDataCommand);

        LoginCommand = loginCommand;
    }
}

Si noti che il metodo di login e il metodo di caricamento dei dati sono entrambi metodi asincroni.

Qual è una buona pratica per gestire una situazione del genere?

E anche se volessi impostare la finestra su un certo stato (ad esempio in grigio o mostrando una modal 'wait') fino al termine del caricamento?

    
posta Bishoy 23.11.2017 - 06:54
fonte

1 risposta

1

Creerei un singolo DelegateCommand per chiamare Login e LoadData in modo tale da avere il controllo sull'ordine in cui sono chiamati:

LoginAndLoadMasterDataCommand = new DelegateCommand(
    async () =>
    {
        IsLoading = true;

        bool loginSuccesful = await client.Login();
        if (loginSuccesful)
            await MasterData.LoadData();

        IsLoading = false;
    }

IsLoading è una proprietà osservabile che puoi associare a ProgressBar o alla Visibilità di altri controlli per fornire un feedback all'utente che l'applicazione sta funzionando. E MasterData.LoadData è, apparentemente, il metodo attendibile che il tuo MasterData.LoadDataCommand sta chiamando.

    
risposta data 30.11.2017 - 11:32
fonte

Leggi altre domande sui tag