Hallo Leute,
ich hab da ein kleines Problem mit den Commands. Ich habe mir eine eigene Command Klasse geschrieben, jedoch wird die CanExecute Methode nur einmal aufgerufen und danach nie wieder.
im ViewModel
CmdSave = new MyCommand((obj) =>
{
//do something
});
CmdSave.CanExecuteAction = (obj) =>
{
//do something
};
public class MyCommand: ICommand
{
public Func<object, bool > CanExecuteAction = (obj) => { return true; };
public Action<object> ExecuteAction;
public iDSCommand(Action<object> aExecuteAction)
{
ExecuteAction = aExecuteAction;
}
public bool CanExecute(object parameter)
{
return CanExecuteAction(parameter);
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
ExecuteAction(parameter);
}
}
<Button Command="{Binding CmdSave}" Margin="0,20,0,0" HorizontalAlignment="Right" Style="{DynamicResource myButton}">
Speichern
</Button>
Häng das CanExecuteChanged Event mal an das CommandManager.RequerySuggested.
Ich würde mir das CanExecuteAction auch über den Konstruktor geben lassen und in der public bool CanExecute(object parameter) Methode lieferst du
return CanExecuteAction == null || CanExecuteAction()
zurück
Häng das CanExecuteChanged Event mal an das CommandManager.RequerySuggested.
Sry da steh ich jetzt auf dem Schlauch, wie meinst du das?
Bei mir sieht das ganze immer so aus, evt. hilft es dir ja weiter.
private ICommand _goToChatErstellenCommand;
public ICommand goToChatErstellenCommand
{
get
{
if (_goToChatErstellenCommand == null)
{
_goToChatErstellenCommand = new RelayCommand(param => goToChatErstellenCommand_ExecuteCommand(param));
}
return _goToChatErstellenCommand;
}
set { _goToChatErstellenCommand = value; }
}
private void goToChatErstellenCommand_ExecuteCommand(object param)
{
//Do Something
}
RelayCommand Class
public class RelayCommand : ICommand
{
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
}
Mfg OddN3ss
Vielen dank!
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
war die Lösung des problems!
Deine Lösung "kann" zu Performance-Problemen führen, da hier nicht gezielt CanExecute aufgerufen wird, sondern vom CommandManager und zwar immer und immer wieder. Je nach dem was du dort alles prüfst, kann das sehr teuer werden. Kann bei Debug-Sessions auch ziemlich nervig sein.
Hier ist ein gutes Video ca ab min 18.
http://channel9.msdn.com/Shows/Visual-Studio-Toolbox/MVVM-Best-Practices
Stimmt schon, ist voll der Anti-Pattern.
aber jede ICommand-Implementation macht das so, von egal welcher Bibliothek.
Auch das System.Windows.Input.RoutedCommand von Microsoft: http://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Input/Command/RoutedCommand.cs,bad35753824e03de
Der frühe Apfel fängt den Wurm.