Laden...

WPF: Command CanExecute wird nur einmal aufgerufen

Erstellt von Coooder vor 8 Jahren Letzter Beitrag vor 8 Jahren 2.320 Views
C
Coooder Themenstarter:in
180 Beiträge seit 2011
vor 8 Jahren
WPF: Command CanExecute wird nur einmal aufgerufen

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>
R
228 Beiträge seit 2013
vor 8 Jahren

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

C
Coooder Themenstarter:in
180 Beiträge seit 2011
vor 8 Jahren

Häng das CanExecuteChanged Event mal an das CommandManager.RequerySuggested.

Sry da steh ich jetzt auf dem Schlauch, wie meinst du das?

O
15 Beiträge seit 2015
vor 8 Jahren

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

C
Coooder Themenstarter:in
180 Beiträge seit 2011
vor 8 Jahren

Vielen dank!

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

war die Lösung des problems!

V
15 Beiträge seit 2015
vor 8 Jahren

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

5.299 Beiträge seit 2008
vor 8 Jahren

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.