WPF ICommand над кнопкой - PullRequest
       14

WPF ICommand над кнопкой

0 голосов
/ 29 марта 2010

Я реализовал пользовательский класс IComand для одной из моих кнопок. Кнопка размещается на странице «MyPage.xaml», но ее собственный класс ICommand размещается в другом классе, а не в коде MyPage позади. Затем из XAML я хочу связать кнопку с ее собственным классом команд, а затем делаю:

MyPage.xaml:

    <Page ...>

         <Page.CommandBindings>
             <CommandBinding Command="RemoveAllCommand"
                CanExecute="CanExecute"
                Executed="Execute" />
         </Page.CommandBindings>

         <Page.InputBindings>
                <MouseBinding Command="RemoveAllCommand" MouseAction="LeftClick" />
         </Page.InputBindings>

             <...>
               <Button x:Name="MyButton"  Command="RemoveAllCommand" .../>
             <...>

    </Page>

и класс пользовательских командных кнопок:

// Here I derive from MyPage class because I want to access some objects from 
// Execute method
public class RemoveAllCommand : MyPage, ICommand 
{

    public void Execute(Object parameter)
    {
        <...>
    }

    public bool CanExecute(Object parameter)
    {
        <...>
    }


    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }  

}

Моя проблема в том, как сказать MyPage.xaml, что методы Execute и CanExecute для кнопки находятся в другом классе, а не в коде, где находится кнопка. Как сказать, что эти методы находятся в классе RemoveAllCommand на странице XAML.

Также я хочу запустить эту команду, когда в кнопке создается событие щелчка мыши, поэтому я выполняю привязку ввода, это правильно?

Спасибо

Ответы [ 3 ]

1 голос
/ 29 марта 2010

Поскольку у вас есть ICommand, вы можете привязать ее к кнопке через свойство Command, и кнопка будет использовать ее, то есть она вызовет CanExecute для включения / выключения себя и метод Execute при нажатии кнопки. Никакой другой привязки ввода не требуется.

Теперь проблема в том, что кнопка должна найти команду. Простое решение - поместить экземпляр команды в DataContext кнопки (или ее родителей).

Если DataContext имеет свойство RemoveAll типа RemoveAllCommand, вы можете просто изменить кнопку XAML на:

<Button Command="{Binding RemoveAll}" .. />

и удалите CommandBinding и InputBinding

0 голосов
/ 29 марта 2010

ок, спасибо, завтра попробую.

Теперь, чтобы избежать проблем, я переместил все в классе RemoveAllCommandClass в код позади MyPage и сделал несколько модификаций.

1.- Я добавил это в MyPage.xaml:

XMLNS: местные = "CLR-пространств имен: GParts"

тогда я сделал:

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


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

И все в порядке и работает. Когда я нажимаю кнопку, он выполняет фоновый рабочий (bw), который вызывается в методе Execute. BW в другой класс. В фоновом рабочем классе у меня есть переменная (isRunning), которая указывает, выполняется ли bw. Перед выполнением события DoWork я установил его в true, а когда bw завершил, в RunWorkerCompleted я установил его в false. Поэтому из CanExecute я проверяю isRunning в классе bw и устанавливаю в true e.canExecute, если isRunning - false, и e.canExecute в false, если isRunning - true Таким образом, WPF автоматически отключает кнопку, когда bw работает, но когда bw завершает работу, кнопка продолжает отключаться и не возвращается к включенной, пока я не нажму ее снова. Почему WPF не обновляет состояние кнопки до включенного, когда bw завершает работу, пока я снова не нажму кнопку?

Спасибо.

0 голосов
/ 29 марта 2010

Эй, я сделал это, но безуспешно, при сборке проекта я получил ошибку: не удается создать экземпляр типа RemoveAllCommand.

Я сделал это:

MyPage.xaml (я удалил CommandBinding и InputBinding со страницы):

<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:Classes="clr-namespace:GParts.Classes"   
xmlns:Pages="clr-namespace:GParts.Pages">

<Page.Resources>
      <...>
         <Pages:RemoveAllCommand x:Key="RemoveAllCommandInstance"/>
      <...>
</Page.Resources>

<...>
<Button Command="{Binding RemoveAllCommandInstance}" ...>  
<...>
</Page>

В пользовательском классе Icommand я добавил конструктор без параметров:

public class RemoveAllCommand : MyPage, ICommand 
{

    public RemoveAllCommand() { }

    ...
}

Спасибо.

...