Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 满足条件时CanExecute()未启用按钮_C#_Wpf_Relaycommand - Fatal编程技术网

C# 满足条件时CanExecute()未启用按钮

C# 满足条件时CanExecute()未启用按钮,c#,wpf,relaycommand,C#,Wpf,Relaycommand,我有一个非常简单的应用程序,它有一个文本框和一个按钮。当输入到文本框中的文本长度超过5个字符时,按钮将被启用。以下是我的ViewModel的代码: private string _text { get; set; } public string Text { get { return _text; } set { _text = value; OnPropertyChanged("Text"); } } private IComm

我有一个非常简单的应用程序,它有一个
文本框
和一个
按钮
。当输入到
文本框中的文本长度超过5个字符时,按钮将被启用。以下是我的ViewModel的代码:

private string _text { get; set; }
public string Text
{
    get { return _text; }
    set
    {
        _text = value;
        OnPropertyChanged("Text");
    }
}

private ICommand _buttonCommand;
public ICommand ButtonCommand
{
    get
    {
        if (_buttonCommand == null)
        {
            _buttonCommand = new RelayCommand(
                param => this.ButtonCommandExecute(), 
                param => this.ButtonCommandCanExecute()
            );
        }
        return _buttonCommand;
    }
}

private bool ButtonCommandCanExecute()
{
    if (this.Text.Length < 5)
    {
        return false;
    }
    else
    {
        return true;
    }
}

private void ButtonCommandExecute()
{
    this.Text = "Text changed";
}

public MainWindowViewModel()
{
    //
}
DataContext
似乎设置正确,但这只是因为我是WPF初学者:

private MainWindowViewModel view_model;

public MainWindow()
{
    InitializeComponent();

    view_model = new MainWindowViewModel();

    this.DataContext = view_model;
}

当我在
文本框
中键入时,
按钮
从不启用。

实际上,您必须使Bool属性绑定到按钮控件的IsEnabled属性。当文本框中的文本超过五个字符时,请将此属性设置为true。您必须在文本属性的Setter中执行此操作,因为这是您在文本框中键入时所调用的

Basic About Commands:这些命令基本上用于向C#code报告点击事件,比如你的Viewmodel/Page.cs。以便您可以执行某些任务。它与按钮的启用和禁用无关

请遵循以下代码:-

private string _text { get; set; }
public string Text
{
    get { return _text; }
    set
    {
        _text = value;

        if(_text.Length  > 5)
        // Enable button here
        // and command does not enable Buttons they are basically report the clicks events.
        IsButtonEnabled = true;

        OnPropertyChanged("Text");
    }
}
要启用按钮,请创建名为IsButtonEnabled的布尔类型属性,并将此属性绑定到Xaml中的按钮

private bool _IsButtonEnabled { get; set; }
public bool IsButtonEnabled
{
    get { return _IsButtonEnabled ; }
    set
    {
        _IsButtonEnabled = value;
        OnPropertyChanged("IsButtonEnabled");
    }
}
在Xaml中:-

<Button Content="Button" HorizontalAlignment="Left" 

             IsEnabled="{Binding IsButtonEnabled}"

            Margin="185,132,0,0" VerticalAlignment="Top" Width="120"
            Command="{Binding Path=ButtonCommand}" />

尝试对您的代码进行这一小小的修改,并告诉我它是否有效:

private string _text { get; set; }
public string Text
{
    get { return _text; }
    set
    {
        _text = value;
        OnPropertyChanged("Text");
        ButtonCommandCanExecute();
    }
}

private ICommand _buttonCommand;
public ICommand ButtonCommand
{
    get
    {
        if (_buttonCommand == null)
        {
            _buttonCommand = new RelayCommand(
                param => this.ButtonCommandExecute(), 
                param => this.ButtonCommandCanExecute()
            );
        }
        return _buttonCommand;
    }
}

private bool ButtonCommandCanExecute()
{
    if (this.Text.Length < 5)
    {
        return false;
    }
    else
    {
        return true;
    }
}

private void ButtonCommandExecute()
{
    this.Text = "Text changed";
}

public MainWindowViewModel()
{
    //
}
私有字符串_text{get;set;}
公共字符串文本
{
获取{return\u text;}
设置
{
_文本=值;
OnPropertyChanged(“文本”);
按钮命令和CanExecute();
}
}
私有ICommand _按钮命令;
公用ICommand按钮命令
{
得到
{
如果(_buttonCommand==null)
{
_按钮命令=新继电器命令(
param=>this.buttonCommand执行(),
param=>this.ButtonCommandCanExecute()
);
}
返回按钮命令;
}
}
私有布尔按钮命令和CanExecute()
{
if(this.Text.Length<5)
{
返回false;
}
其他的
{
返回true;
}
}
私有void按钮命令执行()
{
this.Text=“Text changed”;
}
公共主窗口视图模型()
{
//
}

ICommand
接口的一些实现有特殊的方法来通知“CanExecute”是否已更改
RelayCommand
class(MVVM灯)有这样的方法

private string _text;
public string Text
{
    get { return _text; }
    set
    {
        _text = value;
        OnPropertyChanged("Text");

        // There is a special RelayCommand method to notify "CanExecute" changed.
        // After this call, the "CanExecute" state is "re-evaluated" automatically by binding using CanExecute Func passed into RelayCommand constructor.
        _buttonCommand.RaiseCanExecuteChanged();
    }
}

private RelayCommand _buttonCommand;
public ICommand ButtonCommand
{
    get
    {
        if (_buttonCommand == null)
        {
            _buttonCommand = new RelayCommand(
                param => this.ButtonCommandExecute(), 
                param => this.ButtonCommandCanExecute()
            );
        }
        return _buttonCommand;
    }
}

这个问题可能很有用:

如果您将选项卡从文本框中移出,它是否正确启用/禁用?
TextBox.Text
的默认绑定模式是
OnLostFocus
,因此在
TextBox
失去焦点之前,数据不会保留回VM。要更改此设置,可以将绑定
模式
属性设置为
PropertyChanged
。另外,您正在使用哪种类型的RelayCommand?如果是MVVM light relay命令,那么每当属性发生更改时,它应该会自动启动
CanExecuteChanged
和requery
CanExecute
,但是并非所有的中继命令都是这样。这也是一个问题,非常感谢Rachel。我的朋友,非常感谢!我做了你说的有意义的事情,但是你能详细说明IsButtonneEnabled的绑定吗?我是否将其绑定到按钮的IsEnabled属性?@user3761858 yes bro。我在ans的底部添加了一个代码:)注意:不需要额外的属性。将命令(字段)存储为
RelayCommand
,只需调用
RelayCommand.raisecannexecutechanged()
OnPropertyChanged(“Text”)
之后@SergeyBrunov您的意思是说如果之前禁用了按钮,它将启用该按钮?@SergeyBrunov谢谢,我不知道:)我尝试了。只是去睡觉。现在使用我的选项卡。这将不起作用:-启用/禁用按钮的代码在哪里?这是正确的答案,因为它允许ICommand按设计工作,并且不需要额外的属性或绑定。
private string _text;
public string Text
{
    get { return _text; }
    set
    {
        _text = value;
        OnPropertyChanged("Text");

        // There is a special RelayCommand method to notify "CanExecute" changed.
        // After this call, the "CanExecute" state is "re-evaluated" automatically by binding using CanExecute Func passed into RelayCommand constructor.
        _buttonCommand.RaiseCanExecuteChanged();
    }
}

private RelayCommand _buttonCommand;
public ICommand ButtonCommand
{
    get
    {
        if (_buttonCommand == null)
        {
            _buttonCommand = new RelayCommand(
                param => this.ButtonCommandExecute(), 
                param => this.ButtonCommandCanExecute()
            );
        }
        return _buttonCommand;
    }
}