我已经在我的桌面 WPF 非银光应用程序中实现了 prism MVVM 模式。在屏幕加载期间,我正在用一组值填充一个列表框。此列表框绑定(bind)到 ViewModel(这是我的 DataContext),并且每个项目都使用 DataTemplate 呈现。这工作正常。然后我尝试创建一个文本框,允许用户在输入时过滤显示哪些记录。我的自然想法是跟踪 KeyUp 或 TextChanged 事件,但事实证明,如果尝试按照建议保持对 ICommand 的使用,这比绑定(bind)到事件更困难。我找不到解决这个问题的简单方法,也不想再花时间解决这个问题,因为我的最后期限快到了。考虑到这一点,我尝试了以下解决方案:
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();
}
View 模型:
//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 文本每次都是空的。开始让我难以置信的是,如果我点击了我在屏幕上制作的保存按钮,它直接点击了 DelegateCommmand,如下所示:
<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
的默认值属性是 LostFocus
对于 TextBox
,这就是为什么在您将焦点从文本框移到另一个控件(在您的情况下,点击按钮)之前,您的 ViewModel 属性不会更新的原因。设置UpdateSourceTrigger
的值至PropertyChanged
在你的绑定(bind)中。
例如:
<TextBox Name="ChannelSearch"
Text="{Binding Path=ChannelFilter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
TextChanged="ChannelSearch_TextChanged" />
请参阅此 MSDN article阅读有关 UpdateSourceTrigger 属性的更多信息。
对于您最初的问题,您可以调用
doFilterChannels
来自 ChannelFilter
的 setter 的方法viewModel 上的属性(当然,不会阻塞 UI 线程)。
关于c# - WPF Prism Bound 字段值在命令触发之前不可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19163550/