C# 可以执行Null

C# 可以执行Null,c#,xaml,mvvm,data-binding,C#,Xaml,Mvvm,Data Binding,我遇到了WPF和绑定到视图中某个按钮的命令的问题,我一直在学习有关命令的教程,似乎无法理解为什么它会被卡住。调用传递给CanExecute的参数时为null 我有一个表单,当我按Add时,它的文本框绑定到我的属性。我想将股票添加到列表中 我的看法 <TextBox Grid.Column="1" Grid.Row="1" Margin="2" VerticalAlignment="Top" Width

我遇到了WPF和绑定到视图中某个按钮的命令的问题,我一直在学习有关命令的教程,似乎无法理解为什么它会被卡住。调用传递给CanExecute的参数时为null

我有一个表单,当我按Add时,它的文本框绑定到我的属性。我想将股票添加到列表中

我的看法

 <TextBox  Grid.Column="1" Grid.Row="1"   Margin="2"  VerticalAlignment="Top" Width="178" Text="{Binding Ticker,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/>
                    <DatePicker  Grid.Column="1" Grid.Row="2" Name="txtDate"  Margin="2"  VerticalAlignment="Top" Width="178" Text="{Binding Date,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"/>
                    <TextBox  Grid.Column="1" Grid.Row="3" Name="txtPriceEntry"  Margin="2"  VerticalAlignment="Top" Width="178" Text="{Binding PreviousClose,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
                    <TextBox  Grid.Column="1" Grid.Row="4" Name="txtOpeningPriceEntry"  Margin="2"  VerticalAlignment="Top" Width="178"   Text="{Binding OpeningPrice,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
                    <TextBox Grid.Column="1" Grid.Row="5" Name="txtHighEntry"  Margin="2"  VerticalAlignment="Top" Width="178"   Text="{Binding High,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
                    <TextBox  Grid.Column="1" Grid.Row="6" Name="txtLowEntry"  Margin="2"  VerticalAlignment="Top" Width="178"   Text="{Binding Low,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
                    <TextBox Grid.Column="1" Grid.Row="7" Name="txtClosingPriceEntry"  Margin="2"  VerticalAlignment="Top" Width="178"  Text="{Binding ClosingPrice,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
                    <Button Grid.Column="1" Grid.Row="8" Name="btnAdd"  Width="100" Height="25" Content="Add" Command="{Binding Command}" />
RelayCommand.cs

public class RelayCommand<T> : ICommand
{
    private readonly Predicate<T> _canExecute;
    private readonly Action<T> _execute;

    public RelayCommand(Action<T> execute)
       : this(execute, null)
    {
        _execute = execute;
    }

    public RelayCommand(Action<T> execute, Predicate<T> canExecute)
    {
        if (execute == null)
        {
            throw new ArgumentNullException("execute");
        }
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute == null || _canExecute((T)parameter);
    }

    public void Execute(object parameter)
    {
        _execute((T)parameter);
    }

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

public class RelayCommand : ICommand
{
    private readonly Predicate<object> _canExecute;
    private readonly Action<object> _execute;

    public RelayCommand(Action<object> execute)
       : this(execute, null)
    {
        _execute = execute;
    }

    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 || _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }

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

    private event EventHandler CanExecuteChangedInternal;

    public void RaiseCanExecuteChanged()
    {
        CanExecuteChangedInternal.Raise(this);
    }
}
公共类RelayCommand:ICommand
{
私有只读谓词_canExecute;
私有只读操作\u执行;
公共中继命令(操作执行)
:此(执行,空)
{
_执行=执行;
}
公共RelayCommand(操作执行,谓词canExecute)
{
if(execute==null)
{
抛出新的ArgumentNullException(“执行”);
}
_执行=执行;
_canExecute=canExecute;
}
公共布尔CanExecute(对象参数)
{
return _canExecute==null | | | u canExecute((T)参数);
}
public void Execute(对象参数)
{
_执行((T)参数);
}
公共事件事件处理程序CanExecuteChanged
{
添加{CommandManager.RequerySuggested+=value;}
删除{CommandManager.RequerySuggested-=value;}
}
}
公共类中继命令:ICommand
{
私有只读谓词_canExecute;
私有只读操作\u执行;
公共中继命令(操作执行)
:此(执行,空)
{
_执行=执行;
}
公共RelayCommand(操作执行,谓词canExecute)
{
if(execute==null)
{
抛出新的ArgumentNullException(“执行”);
}
_执行=执行;
_canExecute=canExecute;
}
公共布尔CanExecute(对象参数)
{
返回_canExecute==null | | | u canExecute(参数);
}
public void Execute(对象参数)
{
_执行(参数);
}
公共事件事件处理程序CanExecuteChanged
{
添加
{
CommandManager.RequerySuggested+=值;
CanExecuteChangeInternal+=值;
}
去除
{
CommandManager.RequerySuggested-=值;
CanExecuteChangeInternal-=值;
}
}
私有事件处理程序CanExecuteChangeInternal;
public void raisecancecutechanged()
{
CanExecuteChangedInternal.升起(此);
}
}

}

您没有将
CanExecute
传递给命令。因此它是
null
。我建议将
Command
重命名为
AddCommand
,以避免命名冲突

private ICommand\u addCommand;
公共ICommand AddCommand
{
得到
{
返回_addCommand???(_addCommand=new RelayCommand)(
x=>
{
AddStock();
},
x=>true//这是可选的CanExecute,请在此处尝试返回'false'
));
}
}

我在RelayCommand类中做了一些更改,并将canExecute参数设置为null,但仍然不起作用,我知道我缺少了一些愚蠢的东西“公共RelayCommand(Action execute,Func canExecute=null){this.\u execute=execute;this.\u canExecute=canExecute;}@F.OLeary我不明白,你到底想实现什么。请参阅。当我运行程序并进入它时,它会触发命令,当它在我的RelayCommand类中点击我的CanExecute方法时,它会继续执行该方法?@F.OLeary您是否尝试了答案中的代码?您是否尝试在那里返回
false
?它必须使按钮处于禁用状态。
public class RelayCommand<T> : ICommand
{
    private readonly Predicate<T> _canExecute;
    private readonly Action<T> _execute;

    public RelayCommand(Action<T> execute)
       : this(execute, null)
    {
        _execute = execute;
    }

    public RelayCommand(Action<T> execute, Predicate<T> canExecute)
    {
        if (execute == null)
        {
            throw new ArgumentNullException("execute");
        }
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute == null || _canExecute((T)parameter);
    }

    public void Execute(object parameter)
    {
        _execute((T)parameter);
    }

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

public class RelayCommand : ICommand
{
    private readonly Predicate<object> _canExecute;
    private readonly Action<object> _execute;

    public RelayCommand(Action<object> execute)
       : this(execute, null)
    {
        _execute = execute;
    }

    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 || _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }

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

    private event EventHandler CanExecuteChangedInternal;

    public void RaiseCanExecuteChanged()
    {
        CanExecuteChangedInternal.Raise(this);
    }
}