在触发命令之前,“WPF 棱镜绑定”字段值不可用
本文关键字:字段 绑定 棱镜 WPF 命令 | 更新日期: 2023-09-27 18:33:58
我已经在我的桌面WPF非silverlight应用程序中实现了棱镜MVVM模式。 在屏幕加载期间,我正在用值集合填充列表框。 此列表框绑定到视图模型(这是我的DataContext(,并且每个项目都使用DataTemplate呈现。 这工作正常。 然后,我正在尝试创建一个文本框,该文本框将允许用户过滤在键入时显示的记录。 我的自然想法是追求 KeyUp 或 TextChanged 事件,但事实证明,如果尝试按照建议维护 ICommand 的使用,这比仅仅绑定到事件更困难。 我找不到解决这个问题的简单方法,也不想再花时间弄清楚它,因为我的最后期限很快就到了。考虑到这一点,我尝试了以下解决方案:
XAML:
<TextBox Name="ChannelSearch" Text="{Binding Path=ChannelFilter, Mode=TwoWay}" TextChanged="ChannelSearch_TextChanged" />
代码隐藏:
private void ChannelSearch_TextChanged(object sender, TextChangedEventArgs e) {
var vm = ((IExpressionEditorViewViewModel)ViewModel);
if (vm.FilterChannels.CanExecute())
vm.FilterChannels.Execute();
}
视图模型:
//In the constructor:
FilterChannels = new DelegateCommand(doFilterChannels, doCanFilterChannels);
//Class properties:
public string ChannelFilter { get; set; }
//Methods used by DelegateCommand:
private void doFilterChannels(){
if (string.IsNullOrWhiteSpace(ChannelFilter))
this.IdFileRows = _allIdFileRows;
else{
var lower = ChannelFilter.Trim().ToLower();
this.IdFileRows = _allIdFileRows.Where(
r => (DisplayChannel && r.A_RowChannelNum.ToLower().Contains(lower))
|| (DisplayMnemonic && r.B_Mnemonic.ToLower().Contains(lower))
|| (DisplayDescription && r.F_Description.ToLower().Contains(lower))
).ToList();
}
}
private bool doCanFilterChannels() {
return true;
}
因此,在所有这些就绪之后,我开始调试。 结果在 KeyUp 和 TextChanged 之间没有差异。 当点击"doFilterChannels"时,ChannelFilter文本每次都是空的。 开始让我难以置信的是,如果我点击我在屏幕上制作的保存按钮,它会直接点击代表通讯,如下所示:
<Button Content="Save" Command="{Binding Path=SaveExpression}"></Button>
SaveExpression = new DelegateCommand(doSaveExpression, doCanSaveExpression);
private void doSaveExpression() {
Result result = new Result();
try {
result.Success = true;
}
catch (Exception e) {
result.ResultMessages.Add(new ResultMessage { ErrorCode = "500", Message = e.ToString() });
}
result.ThrowErrors();
}
private bool doCanSaveExpression() {
return true; //TODO validation
}
当我进入doSaveExpression方法并检查ChannelFilter时,该值就在那里并且准确。 为什么这里会发生这种情况,而不是在触发 KeyUp/TextChanged 事件时?有没有更好的方法来处理这些情况?
UpdateSourceTrigger
属性的默认值是TextBox
的LostFocus
,这就是为什么在将焦点从文本框移到其他控件(在本例中,点击按钮(之前不会更新 ViewModel 属性的原因。将UpdateSourceTrigger
的值设置为PropertyChanged
绑定。
例如:
<TextBox Name="ChannelSearch"
Text="{Binding Path=ChannelFilter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
TextChanged="ChannelSearch_TextChanged" />
请参阅此 MSDN 文章以了解有关 UpdateSourceTrigger 属性的详细信息。
对于您的原始问题,您可以从 viewModel 上ChannelFilter
属性的 setter 调用doFilterChannels
方法(当然,不会阻塞 UI 线程(。