Ich habe ein Formular mit einem Textfeld und einer Schaltfläche.Button-Befehl CanExecute nicht aufgerufen, wenn Eigenschaft geändert
Wenn der Wert dieses Textfelds geändert wurde, ruft der Schaltflächenbefehl die CanExecute-Methode des Befehls nicht auf.
Der Befehlsparameter ist gesetzt, scheint sich aber nicht zu ändern. Nach dem Laden des Fensters bleibt die Schaltfläche deaktiviert.
<TextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Button Content="Save" Command="{Binding SaveChangesCommand}" CommandParameter="{Binding Name}" />
Ich weiß, dass die Bindung funktioniert, weil ich ein Verhalten geschaffen, die ein Ziel empfängt Bindung und erhöhen die CanExecute, wenn die die Bindung ändert.
Mit diesem Verhalten wird das CanExecute normalerweise aufgerufen.
<Button Content="Save" Command="{Binding SaveChangesCommand}">
<i:Interaction.Behaviors>
<behaviors:CallCommandCanExecuteWhenBindingChange Target="{Binding Name}" />
</i:Interaction.Behaviors>
</Button>
Ansichtsmodell:
public class EditViewModel : INotifyPropertyChanged
{
private string _name;
public EditViewModel()
{
SaveChangesCommand = new DelegateCommand(p => SaveChanges(), p => CanSaveChanges());
}
public string Name
{
get { return _name; }
set
{
if (value == _name) return;
_name = value;
OnPropertyChanged();
}
}
public DelegateCommand SaveChangesCommand { get; private set; }
private void SaveChanges()
{
}
private bool CanSaveChanges()
{
return !string.IsNullOrWhiteSpace(Name);
}
}
DelegateCommand:
public interface IBaseCommand : ICommand
{
void OnCanExecuteChanged();
}
public class DelegateCommand : IBaseCommand
{
private readonly Action<object> _execute;
private readonly Func<object, bool> _canExecute;
public DelegateCommand(Action<object> execute, Func<object, bool> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute(parameter);
OnCanExecuteChanged();
}
public void OnCanExecuteChanged()
{
var handler = CanExecuteChanged;
if (handler != null)
handler(this, EventArgs.Empty);
}
}
CallCommandCanExecuteWhenBindingChange:
public class CallCommandCanExecuteWhenBindingChange : Behavior<FrameworkElement>
{
public static readonly DependencyProperty<CallCommandCanExecuteWhenBindingChange, object> TargetProperty;
private ICommandBase _command;
static CallCommandCanExecuteWhenBindingChange()
{
var dependency = new DependencyRegistry<CallCommandCanExecuteWhenBindingChange>();
TargetProperty = dependency.Register(b => b.Target, s => s.OnTargetChange());
}
public object Target
{
get { return TargetProperty.Get(this); }
set { TargetProperty.Set(this, value); }
}
private void OnTargetChange()
{
if (_command == null && AssociatedObject != null)
{
var field = AssociatedObject.GetType().GetProperty("Command");
_command = (IBaseCommand)field.GetValue(AssociatedObject);
}
if (_command != null)
_command.OnCanExecuteChanged();
}
}
Weiß jemand, warum die Schaltfläche nicht die CanExecute nicht nennen?
Wie Schaltfläche Befehl wird ausgelöst, wenn Sie Textbox Text ändern? –
Da das Textfeld an eine Eigenschaft mit Benachrichtigung gebunden ist und das CommandParameter der Schaltfläche an dieselbe Eigenschaft gebunden ist, wird es benachrichtigt und ruft die CanExecute-Methode des Befehls auf. –