2010-03-29 3 views
0

Je lie une commande à un bouton via la propriété de commande et exécute une commande de liaison dans la page où elle est placée. Dans la méthode execute, je crée une instance d'une classe qui contient le worker d'arrière-plan et je le lance (c'est une tâche longue). La classe worker (bw) de l'arrière-plan contient une variable isRunning qui est définie sur true avant l'exécution de la méthode DoWork et sur false lorsque RunWorkerCompleted est exécuté. Ainsi, à partir du code derrière la page où le bouton est placé, dans la méthode CanExecute, j'ai mis e.canExecute à true si bw n'est pas en cours d'exécution (isRunning = false), et e.canExecute à false si isRunning = true. Quand j'appuie sur le bouton, le processus bw est lancé pendant longtemps et le bouton est désactivé. Ok, c'est correct, mais quand le background worker (bw) se termine, le bouton ne redevient pas actif jusqu'à ce que j'appuie à nouveau dessus. Quand il est désactivé et que j'appuie sur (quand bw est fini) il est activé. Pourquoi le bouton ne revient pas automatiquement à activé à la fin du bw?WPF Utilisation des commandes pour ralentir la mise à jour des contrôles de l'interface utilisateur

mon extrait de code:

<Page x:Class="GParts.Pages.MyPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
    xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes; 
    assembly=PresentationFramework.Aero"    
    xmlns:local="clr-namespace:GParts"  
    Loaded="Page_Loaded" 
    Unloaded="Page_Unloaded" 
    Height="Auto"> 

    <Page.CommandBindings> 
    <CommandBinding Command="{x:Static local:Pages.MyPage.rcmd}" 
       Executed="CommandBinding_Executed" 
       CanExecute="CommandBinding_CanExecute"/> 
    </Page.CommandBindings> 

    <...> 
    <Button Command="{x:Static local:Pages.MyPage.rcmd}" /> 

<...> 
</Page> 

Le code derrière de la page:

namespace GParts.Pages 
{ 

    public partial class MyPage : Page 
    { 

    public static RoutedCommand rcmd = new RoutedCommand(); 

    private cBgWorker bw; 

    <...> 

    // ExecutedRoutedEventHandler for the custom button remove all command. 
    private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e) 
    { 

      // get an isntance of the background worker class 
      bw = new cBgWorker(); 

      // start the long task 
      bw.StartTask(); 

    } 

    // CanExecuteRoutedEventHandler for the custom button remove all command. 
    private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e) 
    { 
     // bw is the instance of background worker class 
     if (bw == null) 
     { 
      e.CanExecute = true; 
     } 
     else 
     { 
      e.CanExecute = !bw.isRunning;// isRunning indicates if bw is 
             //executing now   
     } 
    } 

    <...> 

} // end class 
} // end namespace 
+0

Vous pourriez également envisager de passer par vos (nombreuses) questions et de marquer quelques réponses, le cas échéant. Il suffit de cliquer sur le petit "coche" par la réponse qui vous a aidé le plus .... –

Répondre

7

Lorsque votre BackgroundWorker est terminée, appelez CommandManager.InvalidateRequerySuggested();

Par défaut, les commandes ne sont requeried de temps en temps par WPF . Sinon, il y aurait une énorme quantité de frais généraux en appelant constamment "CanExecute" sur chaque implémentation ICommand. L'appel de la méthode ci-dessus force le CommandManager à se mettre à jour immédiatement.

Cela forcera les commandes à réactiver/désactiver de manière appropriée.

Questions connexes