C# 文本框未更新CanExecute
我正在开发一个MVVM应用程序,它有一个保存按钮,如果标题字段为空,我想禁用该按钮 以下是delegatecommand的代码:C# 文本框未更新CanExecute,c#,wpf,mvvm,C#,Wpf,Mvvm,我正在开发一个MVVM应用程序,它有一个保存按钮,如果标题字段为空,我想禁用该按钮 以下是delegatecommand的代码: _clickSaveChangesCommand = new DelegateCommand<string>( (s) => { saveStudentRecord(); //execute }, (s) => { return (_student.Title != null);
_clickSaveChangesCommand = new DelegateCommand<string>(
(s) => { saveStudentRecord(); //execute },
(s) => { return (_student.Title != null); /*Can execute*/ }
);
以下是装订:
<TextBox Name="fldTitle" Text="{Binding Path=Student.Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="300" Height="27" />
当我从viewmodel中更新学生对象时,它会按预期工作。但是,如果我创建了一条新记录并在文本框中键入了一些内容,则该按钮仍不可执行。在我的测试中,如果我尝试显示_student.Title的值,它将以预期的值显示。当_student.Title更改时,您需要做一些事情来引发命令的CanExecuteChanged事件 您正在使用Prism的DelegateCommand吗?如果是这样,安迪发现了。如果得到支持,它可能比下面的建议更可取。但是,这与您的情况类似,因为该属性是孙属性,而不是拥有该命令的类的直接属性 若你们使用的是棱镜,你们可以做到这一点,试着替换学生,看看会发生什么。在2016年,这将打破启用更新的命令。它可能仍然存在 因此,如果这不起作用,这应该起作用 您的DelegateCommand类可能有这样一个方法;它通常被称为RaiseCanceTechChanged或类似的东西 很可能,最好的方法是为学生设置:
@安迪,我错过了他说他在用棱镜的地方。我见过名为DelegateCommand的类,它们与Prism无关,它们只是用委托实现ICommand。我更新了答案。@Andy;还是那样吗?哦。。。是的,看来他们改变了。您可以显式使用raisepropertychanged或observesproperty将其提升。@Andy当用新实例替换Student时会发生什么?命令将监视新学生.Title,还是继续监视旧学生.Title?如果ObserveProperty在OP的案例中起作用,它将是更好的选择。我只是担心不会。我想我已经把它整理好了。谢谢你指点我CanExecuteChanged。事实证明,我是通过在代码中创建viewmodel的新实例而不是重用现有实例来制造问题的。这需要一些额外的谷歌搜索,但最终我决定将“公共事件事件处理程序CanExecuteChanged{add{CommandManager.RequerySuggested+=value;}remove{CommandManager.RequerySuggested-=value;}}}”添加到我的委托实现中,现在它开始工作了。
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();
}
}