简体   繁体   English

文本框未更新CanExecute

[英]Textbox not updating CanExecute

I'm working on an MVVM application that has a Save button that I'd like to disable if the Title field is empty. 我正在使用具有“保存”按钮的MVVM应用程序,如果“标题”字段为空,我想禁用该按钮。

Here's the code for the delegatecommand: 这是委托命令的代码:

        _clickSaveChangesCommand = new DelegateCommand<string>(
            (s) => { saveStudentRecord(); //execute },
            (s) => { return (_student.Title != null);  /*Can execute*/ }
            );

Here's the binding: 这是绑定:

 <TextBox Name="fldTitle" Text="{Binding Path=Student.Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="300" Height="27" />

When I update the student object from within the viewmodel, it works as expected. 当我从视图模型中更新学生对象时,它会按预期工作。 If, however, I create a new record and type something into the textbox, the button remains not executable. 但是,如果我创建新记录并在文本框中键入内容,则该按钮将无法执行。 In my testing, if I try to show the value of _student.Title it shows with the value as expected. 在我的测试中,如果我尝试显示_student.Title的值,则显示为预期值。

You need to do something to raise the command's CanExecuteChanged event when _student.Title changes. _student.Title更改时,您需要执行一些操作来引发命令的CanExecuteChanged事件。

Are you using Prism's DelegateCommand? 您正在使用Prism的DelegateCommand吗? If so, Andy found this answer . 如果是这样,安迪找到了这个答案 If supported, it may be preferable to the suggestion below. 如果支持,它可能比下面的建议更好。 But see this question , which is like your case in that the property is a "grandchild" property, not a direct property of the class that owns the command. 但是, 请参见此问题 ,就像您的情况一样,该属性是“孙代”属性,而不是拥有命令的类的直接属性。

If you are using Prism and you can do that, do try replacing Student to see what happens. 如果您正在使用Prism并且可以做到这一点,请尝试更换Student以查看会发生什么。 In 2016, that would have broken the command enable updating. 在2016年,这将破坏启用更新的命令。 It may still. 可能还是。

So if that doesn't work, this ought to. 因此,如果这不起作用,则应该这样做。

Your DelegateCommand<T> class may have a method that does that; 您的DelegateCommand<T>类可能具有执行该操作的方法; it's often called RaiseCanExecuteChanged() or something like that. 它通常称为RaiseCanExecuteChanged()或类似名称。

Likely, the best way to do this is in the setter for Student : 最好的方法是在Setter for Student

public Student Student
{
    get { return _student; }
    set
    {
        if (value != _student)
        {
            if (_student != null)
            {
                //  You do want to unhook this, otherwise there's a live reference 
                //  to the old _student and it won't be free to be garbage collected. 
                _student.PropertyChanged -= _student_PropertyChanged;
            }

            _student = value;

            if (_student != null)
            {
                _student.PropertyChanged += _student_PropertyChanged;
            }

            OnPropertyChanged();
        }
    }
}

private void _student_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "Title")
    {
        ClickSaveChangesCommand.RaiseCanExecuteChanged();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM