Comment implémenter correctement Indicateur de WPF Étendu Toolkit

Ok, j'ai été aux prises avec ce problème depuis un certain temps et avoir lu l'article après l'article tente de se faire une idée sur la question. Je suis en train de mettre en œuvre le Voyant d'activité et ne suis que partiellement réussi. J'ai une Coquille vue que j'ai enveloppé avec le BusyIndicator comme suit:

<Window x:Class="Foundation.Shell"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:Library.Controls.Views;assembly=Library"
    xmlns:l="clr-namespace:Library.StaticClasses"
    xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
    Name="ShellView"
    Style="{StaticResource BusyWindowStyle}"
    SourceInitialized="Window_SourceInitialized"
    DataContext="{StaticResource ShellVM}">

    <xctk:BusyIndicator x:Name="ShellBusyIndicator" IsBusy="{Binding IsBusy}"  DisplayAfter="0">
        <Grid>
            <!--Content Here -->
        </Grid>
    </xctk:BusyIndicator>

Suivant le modèle MVVM, j'ai un ShellViewModel qui ressemble à ceci:

public class ShellViewModel : ViewModelBase
{
    #region constructor(s)

    public ShellViewModel()
    {
        StateManager.IsBusyChange += new StateManager.IsBusyHandler(IsBusyEventAction);
    }

    #endregion constructor(s)

    #region properties

    private bool _IsBusy;
    public bool IsBusy
    {
        get
        {
            return _IsBusy;
        }
        set
        {
            if (_IsBusy != value)
            {
                _IsBusy = value;
                OnPropertyChanged("IsBusy");
            }
        }
    }

    private string _IsBusyMessage;
    public string IsBusyMessage
    {
        get
        {
            return _IsBusyMessage;
        }
        set
        {
            if (_IsBusyMessage != value)
            {
                _IsBusyMessage = value;
                OnPropertyChanged("IsBusyMessage");
            }
        }
    }

    #endregion properties

    #region actions, functions, and methods

    private void IsBusyEventAction(object sender, EventArgs e)
    {
        if (StateManager.IsBusy)
        {
            this.IsBusy = true;
            this.IsBusyMessage = StateManager.IsBusyMessage;
        }
        else
        {
            this.IsBusy = false;
        }
    }

    #endregion actions, functions, and methods
}

Prochaine, je suis en utilisant une classe statique appelé StateManager que je peux appeler de n'importe où qui va déclencher le voyant d'activité:

public static class StateManager
{
    public static String IsBusyMessage { get; set; }

    public static void IsBusyProcess(Action action)
    {
        IsBusyProcess(action, "Processing...");
    }

    public static void IsBusyProcess(Action action, String isBusyMessage)
    {
        IsBusyMessage = isBusyMessage;
        IsBusy = true;
        Application.Current.Dispatcher.Invoke(action, System.Windows.Threading.DispatcherPriority.Background);
        IsBusy = false;
    }

    private static bool _IsBusy;
    public static bool IsBusy
    {
        get
        {
            return _IsBusy;
        }
        set
        {
            if (_IsBusy != value)
            {
                _IsBusy = value;

                IsBusyChange(null, null);
            }
        }
    }

    public delegate void IsBusyHandler(object sender, EventArgs e);

    public static event IsBusyHandler IsBusyChange;
}

Enfin, je suis le déclenchement de l'indicateur dans le code comme ceci:

StateManager.IsBusyProcess(() =>
        {
            this.Validate();

            if (!HasValidationErrors)
            {
                if (this.CustomerControlVM.SaveCustomer() != 0)
                {
                    VehicleControlVM.VehicleModel.CustomerID = this.CustomerControlVM.CustomerModel.CustomerID;
                    this.VehicleControlVM.SaveVehicle();

                    ComplaintsView complaintsControl = new ComplaintsView();

                    (complaintsControl.DataContext as ComplaintsViewModel).CurrentVehicle = this.VehicleControlVM.VehicleModel;
                    (complaintsControl.DataContext as ComplaintsViewModel).CurrentCustomer = this.CustomerControlVM.CustomerModel;
                    StateManager.LoadView(complaintsControl, PageTransitionType.SlideLeft);
                }
            }

            StateManager.IsBusy = false;
        });

Pour résumer, le StateManager peut être appelée à partir de n'importe où dans l'application. Lorsque le StateManager.IsBusy propriété est modifiée, un événement, qui est pris dans le ShellViewModel, est déclenché. Lorsque cela se produit, le IsBusy propriété dans le ShellViewModel est définie sur true soi-disant origine du IsBusy indicateur pour montrer. La logique fonctionne très bien dans le sens que le IsBusy dans le ShellViewModel est réglé et l'indicateur de evens montre comme prévu. Ce n'est pas le droit de travailler, c'est que l'indicateur de ne pas les animer. Simplement, il reste stagner. J'ai l'impression que c'est un problème thread mais ma compréhension de la thread de l'INTERFACE utilisateur est incliné ou je ne vois pas quelque chose qui devrait être évident pour vous. Je me rends compte de la IsBusy logique ne peut pas être sur le même thread que l'INTERFACE utilisateur, mais je pense que depuis ma logique qui se passe dans le modèle de vue, il ne devrait pas être un problème. Suis-je tort? Toutes les idées ou les pensées? Une autre chose qui pourrait être utile: j'ai eu du mal, même à obtenir l'indicateur à afficher et de créer ce post qui a été résolu: Comment mettre en œuvre voyant d'activité en application shell

  • Donc, ce que d'autres processus en cours d'exécution qui auraient besoin d'un voyant d'activité, il est sur un thread séparé ainsi?
  • Salut Félix. Merci pour votre réponse. Le long processus en cours d'exécution doivent être sur le même thread que l'ShellViewModel sauf si j'ai oublié quelque chose. J'ai tenté d'utiliser les Threads de la fenêtre (que je n'ai jamais utilisé avant), mais il semble indiquer que mon ShellView et ShellViewModel sont à la fois dans le thread principal. Je ne sais pas comment c'est possible donc je ne suis pas fier et je suis confiante que mon propre point de vue, encore moins.
  • il y a aussi un bel article sur: c-sharpcorner.com/UploadFile/mahesh/wpf-busyindicator
InformationsquelleAutor flyNflip | 2014-08-09