ICommand的CanExecute方法如何工作?

时间:2019-10-11 08:03:07

标签: wpf .net-core

我看过一些实现 template<typename T, Integer TransposedRows, Integer TransposedCols> class Transposed<Matrix<T,TransposedRows,TransposedCols>>: public Matrix<T,TransposedRows,TransposedCols> { public: constexpr Transposed(const Matrix<T,TransposedRows,TransposedCols>& mat): mat_ptr_(std::make_shared<Matrix<T,TransposedRows,TransposedCols>>(mat)) {} inline constexpr const auto& operator()() const { return *mat_ptr_; } inline constexpr void operator()(cons Matrix<T,TransposedRows,TransposedCols>& mat) { mat_ptr_=std::make_shared<Matrix<T,TransposedRows,TransposedCols>>(mat); } inline constexpr T &operator()(const Integer& i, const Integer& j) { assert(i < Rows); assert(j < Cols); return (*mat_ptr_)(j,i); } inline constexpr const T &operator()(const Integer i, const Integer j) const { assert(i < Rows); assert(j < Cols); return (*mat_ptr_)(j,i); } private: std::shared_ptr<Matrix<T,TransposedRows,TransposedCols,NonZeroRow>> mat_ptr_; } 的示例,对我来说,以下方法是最简单的:

ICommand

这就是我在测试应用程序中实现的方式。除了class Command : ICommand { public Func<object, bool> CanDo { get; set; } public Action<object> Do { get; set; } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public Command(Func<object, bool> CanDo, Action<object> Do) { this.CanDo = CanDo; this.Do = Do; } public bool CanExecute(object parameter) => CanDo(parameter); public void Execute(object parameter) => Do(parameter); } 类之外,我还有以下类:

Command

class Person : INotifyPropertyChanged { string firstName, lastName, enabled; public string FirstName { get => firstName; set { firstName = value; Changed();} } public string LastName { get => lastName; set { lastName = value; Changed(); } } public string Enabled { get => enabled; set { enabled = value; Changed(); } } public Command MyCommand { get; set; } public event PropertyChangedEventHandler PropertyChanged; public Person() { MyCommand = new Command(CanDo, Do); } void Changed(string name = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); bool CanDo(object para) { if (FirstName == "test" && LastName == "test") { Enabled = "true"; //Changed("Enabled"); return true; } else { Enabled = "false"; //Changed("Enabled"); return false; } } void Do(object para) { FirstName = "first"; LastName = "last"; } } 中,我有这些:

xaml

启动该应用程序后,如果我在<Window ...> <Window.Resources> <local:Person x:Key="person"/> </Window.Resources> <Grid DataContext="{StaticResource person}"> <StackPanel> <TextBox Text="{Binding FirstName}"/> <TextBox Text="{Binding LastName}"/> <TextBlock Text="{Binding FirstName}"/> <TextBlock Text="{Binding LastName}"/> <Button Content="Click" Command="{Binding Path=MyCommand}"/> <Label Content="{Binding Enabled}"/> </StackPanel> </Grid> </Window> 的{​​{1}}中调用TextBox,则我尝试键入那些Changed()的内容都会立即被删除。如果我注释掉setter中的Enabled并取消注释Changed()中的两个setter,它会按预期工作!

Changed("Enabled")中一次调用bool CanDo(object para)等同于在Changed()中两次调用setter吗?

1 个答案:

答案 0 :(得分:1)

您在CallerMemberNameAttribute中缺少Changed

void Changed([System.Runtime.CompilerServices.CallerMemberName]string name = "") => 
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));

这将获取呼叫属性名称,因此您不必在设置器中呼叫Changed("Enabled"),只需呼叫Changed()