2012-05-30 3 views
2

명령을 사용하여 작업하는 방법을 이해하려고합니다. 명령에 대해 많이 읽었습니다. 대부분의 시간 명령은 MVVM 패턴 내에서 사용됩니다. 또한 RoutedCommand 클래스가 있다는 것을 알고 있습니다.이 클래스는 종종 개발하는 동안 시간을 ​​절약하는 데 사용됩니다.MVVM이없는 ICommand 구현 이해

하지만 기본 지식을 알고 싶습니다. 정확히 그 문제입니다. 여기에 우리가 간다 : 내 응용 프로그램에서

내가 클래스를 정의 'MyCommand'

public class MyCommand :ICommand 
{ 
    public void Execute(object parameter) 
    { 
     Console.WriteLine("Execute called!"); 
     CanExecuteChanged(null, null); 
    } 

    public bool CanExecute(object parameter) 
    { 
     Console.WriteLine("CanExecute called!"); 
     return true; 
    } 

    public event EventHandler CanExecuteChanged; 
} 

음 - 나는 수업을하기로 결정 정적 액세스하려면, 단지 모든 응용 프로그램 명령에 대해 :

public static class AppCommands 
    { 
     private static ICommand anyCommand = new MyCommand(); 

     public static ICommand AnyCommand 
     { 
      get { return anyCommand; } 
     } 
    } 

거의 없습니다. 이제 MainWindow에 두 개의 버튼을 넣었습니다. MainWindow.cs을

<StackPanel> 
    <Button Content="Button" Height="23" Name="button1" Width="75" Click="button1_Click" /> 
    <Button Content="Button" Height="23" Name="button2" Width="75" Command="{x:Static local:AppCommands.AnyCommand}" CommandParameter="Hello"/> 
</StackPanel> 

을 그리고 여기에 있습니다 : : 그 중 하나는 명령에 '바인더 제본'입니다

public MainWindow() 


    { 
     InitializeComponent(); 
     AppCommands.AnyCommand.CanExecuteChanged += MyEventHandler; 
    } 


    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     // Nothing for the moment 
    } 

    private void MyEventHandler(object sender, EventArgs e) 
    { 
     Console.WriteLine("MyEventHandler called"); 
    } 

그래서 -의 내 프로젝트를 실행하자. 보시다시피 콘솔 출력을 만들었습니다. button2를 클릭하면 출력은 다음과 같습니다.

CanExecute라는! 실행 호출! CanExecute가 호출되었습니다! MyEventHandler는

을 호출했습니다.

그래서 내 눈에는 이것이 일어납니다. 1. 버튼의 명령이 '활성화 됨'입니다. execute 메서드를 호출해야하는지 확인하려면 CanExecute 메서드가 호출됩니다. 2. CanExecute 메서드가 true를 반환하면 Execute 메서드가 호출됩니다. 3) execute 메서드 내에서 'CanExecuteChanged'이벤트를 발생시켜야한다고 정의했습니다. 그것을 호출하면 'CanExecute'를 먼저 확인한 다음 이벤트 핸들러를 호출합니다.

이것은 나에게 명확하지 않습니다. 이벤트를 호출하는 유일한 방법은 Execute 메서드 내에 있습니다. 그러나 Execute 메서드는 CanExecute를 확인한 후 명령 논리를 통해 호출됩니다. 이벤트를 호출해도 CanExecute를 확인하지만 그 이유는 무엇입니까? 나는 혼란 스럽다.

버튼을 비활성화하려고하면 상황이 더욱 혼란 스럽습니다. 'CommandParameter'가 있으며 'CanExecute'가 이제 작동합니다. 따라서 메소드가 false를 리턴 할 수 있습니다. 이 경우 버튼이 비활성화됩니다.

하지만 어떻게 재 활성화합니까? 우리가 이미 알고있는 것처럼 : 나는 나의 명령 클래스 내에서만 CanExecuteChange 이벤트를 발생시킬 수있다. 따라서 비활성화 된 버튼을 클릭 할 수 없으므로 명령이 CanExecute (또는 Execute) 메서드를 호출하지 않습니다.

나는 볼 수없는 중요한 것이있다. 그러나 나는 정말로 그것을 발견 할 수 없다.

도와 주시겠습니까?

+0

나는 주제를 둘러싼 폭이 넓어 지도록 태그를 수정했습니다. WPF를 선택했으나 이것이 Silverlight/WP인지 확실하지 않습니다. –

답변

5

CanExecuteChangedExecute까지 올려서는 안되며, CanExecute이 다른 값을 반환하기 시작할 때 올려야합니다. 그것이 명령 클래스에 달려있을 때입니다.가장 간단한 형태로 속성을 추가 할 수 있습니다 :

public class MyCommand : ICommand 
{ 
    bool canExecute; 

    public void Execute(object parameter) 
    { 
     Console.WriteLine("Execute called!"); 
    } 

    public bool CanExecute(object parameter) 
    { 
     Console.WriteLine("CanExecute called!"); 
     return CanExecuteResult; 
    } 

    public event EventHandler CanExecuteChanged; 

    public bool CanExecuteResult 
    { 
     get { return canExecute; } 
     set { 
      if (canExecute != value) 
      { 
       canExecute = value; 
       var canExecuteChanged = CanExecuteChanged; 
       if (canExecuteChanged != null) 
        canExecuteChanged.Invoke(this, EventArgs.Empty); 
      } 
     } 
    } 
} 
+1

대단하다! 해결책은 너무 쉽기 때문에 아플 수 있습니다. 고맙습니다. - 내 하루를 보냈습니다! – CodeCannibal

+0

전체 프로젝트 파일을 답안에 넣을 수 있습니까? – Fulproof

+0

@Fulproof 이상한 질문입니다. 읽을 수없는 XML로 인해이 답변이 개선되지는 않을 것이므로, 아니오라고 말하면서 유혹을 느낍니다. 그렇게하지 않을 것입니다. 그러나 당신이이 문제의 어떤 부분을 설명 할 수 있다면 문제가있는 것입니다. 나는 기꺼이 살펴볼 것입니다. – hvd