WPF Использование команд для замедления обновления элементов управления пользовательского интерфейса - PullRequest
0 голосов
/ 30 марта 2010

Я привязываю команду к кнопке через свойство команды и выполняю привязку команды на странице, на которой она размещена. В методе execute я создаю экземпляр класса, который содержит фоновый рабочий, и запускаю его (это длинная задача). Фоновый рабочий класс (bw) содержит переменную isRunning, для которой задано значение true до выполнения метода DoWork и значение false при выполнении RunWorkerCompleted. Таким образом, из кода позади страницы, где расположена кнопка, в методе CanExecute я установил для e.canExecute значение true, если bw не запущен (isRunning = false), и для e.canExecute значение false, если isRunning = true.

Когда я нажимаю кнопку, она долго запускает процесс, и кнопка отключается. Хорошо, это правильно, но когда фоновый рабочий (bw) завершает работу, кнопка не возвращается к включенной, пока я не нажму ее снова. Когда он отключен, и я нажимаю (когда bw закончится), он включается. Почему кнопка не возвращается автоматически к включенному в конце bw?

мой фрагмент кода:

<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>

Код страницы:

 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

1 Ответ

7 голосов
/ 30 марта 2010

Когда ваш BackgroundWorker завершит работу, позвоните CommandManager.InvalidateRequerySuggested();

По умолчанию команды запрашиваются WPF только изредка. В противном случае при каждом вызове ICommand будет постоянно требоваться постоянный вызов CanExecute. Вызов вышеупомянутого метода заставляет CommandManager обновляться немедленно.

Это заставит Команды соответствующим образом повторно включить / отключить.

...