在触发命令之前,“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 事件时?有没有更好的方法来处理这些情况?

在触发命令之前,“WPF 棱镜绑定”字段值不可用

UpdateSourceTrigger属性的默认值是TextBoxLostFocus,这就是为什么在将焦点从文本框移到其他控件(在本例中,点击按钮(之前不会更新 ViewModel 属性的原因。将UpdateSourceTrigger的值设置为PropertyChanged绑定。

例如:

<TextBox Name="ChannelSearch" 
         Text="{Binding Path=ChannelFilter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  
         TextChanged="ChannelSearch_TextChanged" />

请参阅此 MSDN 文章以了解有关 UpdateSourceTrigger 属性的详细信息。

对于您的原始问题,您可以从 viewModel 上ChannelFilter属性的 setter 调用doFilterChannels方法(当然,不会阻塞 UI 线程(。