2010-03-29 3 views
0

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

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.

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

Благодаря

ответ

1

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

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

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

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

и удалить CommandBinding и InputBinding

+0

Эй, я сделал это, но без успеха, я получил ошибку при создании проекта: Невозможно создать экземпляр типа RemoveAllCommand. Я объясняю это в ответе. – toni

0

Эй, я это сделал, но с нет успеха, я получил ошибку при создании проекта: Не удается создать экземпляр типа 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() { } 

    ... 
} 

Спасибо.

+1

Здесь проблема заключается в том, что вы должны использовать {StaticResource RemoveAllCommandInstance}, чтобы получить команду. – Timores

0

О.К., спасибо, завтра я попробую.

Теперь, чтобы избежать проблем, я переместил все в классе 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

Вы должны сообщить WPF, что состояние команды изменилось. Для этой цели существует событие CanExecuteChanged. – Timores

Смежные вопросы