我有一个包含一些“应用程序”对象的列表框。可以启动或停止“应用程序”对象。
对于我的列表框中的每个元素,我有2个按钮,第一个启动应用程序,第二个停止应用程序。
但是,当我点击“开始”按钮时,在我点击应用程序内部之前,不会重新评估CanExecute命令“停止”,尽管“CommandManager.InvalidateRequerySuggested();”
<ListBox Grid.Row="1" ItemsSource="{Binding Applications}" Grid.ColumnSpan="3" BorderThickness="0" Background="#FFE8E8E8" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Margin="5,0" Content = "Start"
Command="{Binding StartCommand}"
Visibility="{Binding IsRunning, Converter={Converters:InvertedBoolToVisibilityConverter}}"/>
<Button Margin="5,0" Content = "Stop"
Command="{Binding StopCommand}"
Visibility="{Binding IsRunning, Converter={Converters:BoolToVisibilityConverter}}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
在ApplicationViewModel上:
public bool IsRunning
{
get
{
return this.m_IsRunning;
}
set
{
this.m_IsRunning = value;
this.OnPropertyChanged("IsRunning");
CommandManager.InvalidateRequerySuggested();
}
}
public ICommand StartCommand
{
get
{
if (this.m_StartCommand == null)
{
this.m_StartCommand = new RelayCommand(p => !this.IsRunning, p => this.Start());
}
return this.m_StartCommand;
}
}
public ICommand StopCommand
{
get
{
if (this.m_StopCommand == null)
{
this.m_StopCommand = new RelayCommand(p => this.IsRunning, p => this.Stop());
}
return this.m_StopCommand;
}
}
我的RelayCommand类:
public class RelayCommand : ICommand
{
#region Member Fields
/// <summary>
/// Contains the list of actions.
/// </summary>
private readonly Action<object> _execute;
/// <summary>
/// Contains the predicate _canExecute.
/// </summary>
private readonly Predicate<object> _canExecute;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="RelayCommand"/> class.
/// </summary>
/// <param name="execute">The execute.</param>
public RelayCommand(Action<object> execute)
: this(null, execute)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RelayCommand"/> class.
/// </summary>
/// <param name="canExecute">The can execute.</param>
/// <param name="execute">The execute.</param>
public RelayCommand(Predicate<object> canExecute, Action<object> execute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
this._execute = execute;
this._canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
/// <summary>
/// Occurs when changes occur that affect whether or not the command should execute.
/// </summary>
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
/// <summary>
/// Defines the method that determines whether the command can execute in its current state.
/// </summary>
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param>
/// <returns>
/// true if this command can be executed; otherwise, false.
/// </returns>
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return this._canExecute == null ? true : this._canExecute(parameter);
}
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to null.</param>
public void Execute(object parameter)
{
this._execute(parameter);
}
#endregion
}
答案 0 :(得分:3)
直接在RaiseCanExecuteChanged()
的处理程序中试用StopCommand
StartCommand
。
如果你自己实现了你的命令,那么你可以像这样添加RaiseCanExecuteChanged。它将调用CanExecuteChanged事件
public void RaiseCanExecuteChanged()
{
if (CanExecuteChanged != null)
{
CanExecuteChanged(this, EventArgs.Empty);
}
}