2016-05-03 17 views
0

Ich habe ein Problem mit einem CanExecuteChanged-Ereignishandler.CanExecuteChanged funktioniert nicht richtig

Ich habe eine abstrakte Klasse, die ICommand implementiert:

public abstract class CommandBase<TViewModel> : ICommand 
{ 
    protected TViewModel ViewModel { get; set; } 

    public event EventHandler CanExecuteChanged; 

    protected CommandBase(TViewModel viewModel) 
    { 
     this.ViewModel = viewModel; 
    } 

    public virtual bool CanExecute(object parameter) 
    { 
     return true; 
    } 

    public abstract void Execute(object parameter); 
} 

dann habe ich einen Befehl, der von dieser Basis Befehl erbt:

public class AddNewFilmWindowCommand : CommandBase<ViewModelCollection<FilmModel>> 
{ 
    public event EventHandler CanExecuteChanged; 
    public AddNewFilmWindowCommand(ViewModelCollection<FilmModel> viewModelCollection) 
     : base(viewModelCollection) 
    { 
    } 

    public override void Execute(object item) 
    { 
     this.ViewModel.NewItem = new FilmModel(); 

     var onCanExecuteChanged = this.CanExecuteChanged; 
     if (onCanExecuteChanged != null) 
     { 
      onCanExecuteChanged(this, new EventArgs()); 
     } 
    } 

    public override bool CanExecute(object parameter) 
    { 
     if (this.ViewModel.NewItem == null) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 
} 

aber die CanExecuteChanged mir gibt Warnung:

Warnung CS0108 'AddNewFilmWindowCommand.CanExecuteChanged' blendet das geerbte Element 'CommandBase> .CanExe aus cuteChanged '. Verwenden Sie das neue Schlüsselwort, wenn das Ausblenden beabsichtigt war. SpravaFilmu.ViewModels

und ist immer Null. Es wird nie ausgegraut, wenn ich mit diesem Befehl auf die Schaltfläche klicke.

Antwort

1

die Veranstaltung Stellen in CommandBase abstrakt.

public abstract event EventHandler CanExecuteChanged; 

Der UI-Framework Sie sind wahrscheinlich nur mit kennt ICommand. Da Ihre Unterklasse das Ereignis nicht überschreibt, wird die Benutzeroberfläche an das Ereignis in der Basisklasse gebunden. Wenn Sie auf die Schaltfläche klicken, wird das Ereignis in der Unterklasse, aber nicht in der Basisklasse ausgelöst. Im Grunde haben Sie hier 2 Ereignisse - die Benutzeroberfläche verweist auf eine von ihnen, aber Sie heben die andere auf.

+0

Hi, danke, das hat das Problem gelöst :) Perfekt! Daran werde ich mich für das nächste Mal erinnern! – Shadowmak

0

AddNewFilmWindowCommand erbt von CommandBase. Sie haben beide das Ereignis CanExecuteChanged, und in der Befehlsbasis ist es nicht abstrakt oder virtuell. Wenn Sie es beabsichtigt, verwenden Sie das Ereignis aus der Basisklasse außer Kraft setzen dann das neue Stichwort:

public class AddNewFilmWindowCommand : CommandBase<ViewModelCollection<FilmModel>> 
{ 
    public new event EventHandler CanExecuteChanged; 
    ... 
+0

Hallo! Vielen Dank für Ihre Zeit. Ich habe das versucht und immer noch das Ergebnis ist NULL, so wird es nie die if-Anweisung übergeben :(also ich frage mich, was ursprünglich EventHandler auf etwas gesetzt? Ich habe ein anderes referenziertes Projekt, wo der Event-Handler in der if-Anweisung auf etwas bereits gesetzt ist. – Shadowmak

0

Sie können nicht ein Ereignis in einer Basisklasse erhöhen ... aber man könnte eine geschützte Methode, dies zu tun ... so in CommandBase add:

protected void RaiseCanExecuteChanged() 
{ 
    CanExecuteChanged?.Invoke(this, new EventArgs()); 
} 

Und dann in Ihrer Implementierung, nur Deklarieren Sie das Ereignis nicht und nennen Sie es wie folgt:

public override void Execute(object item) 
{ 
    this.ViewModel.NewItem = new FilmModel(); 
    RaiseCanExecuteChanged(); 
}