首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >WPF棱镜绑定字段值在命令启动之前不可用

WPF棱镜绑定字段值在命令启动之前不可用
EN

Stack Overflow用户
提问于 2013-10-03 15:47:14
回答 1查看 536关注 0票数 1

我已经在我的桌面WPF非银光应用程序中实现了棱镜MVVM模式。在屏幕加载期间,我将使用一个值集合填充一个列表框。这个列表框绑定到ViewModel (这是我的DataContext ),每个项目都使用DataTemplate呈现。这很好用。然后,我试图创建一个文本框,允许用户筛选哪些记录在输入时显示。我的自然想法是追求KeyUp或TextChanged事件,但事实证明,如果按照推荐的方式保持ICommand的使用,这比绑定到事件要困难得多。我找不到一个简单的方法来解决这个问题,我不想花更多的时间来解决这个问题,因为我的最后期限快到了。考虑到这一点,我尝试了以下解决方案:

XAML:

代码语言:javascript
运行
复制
<TextBox Name="ChannelSearch" Text="{Binding Path=ChannelFilter, Mode=TwoWay}"  TextChanged="ChannelSearch_TextChanged" />

代码隐藏:

代码语言:javascript
运行
复制
private void ChannelSearch_TextChanged(object sender, TextChangedEventArgs e) {
        var vm = ((IExpressionEditorViewViewModel)ViewModel);
        if (vm.FilterChannels.CanExecute())
            vm.FilterChannels.Execute();
    }

ViewModel:

代码语言:javascript
运行
复制
 //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,如下所示:

代码语言:javascript
运行
复制
<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事件时呢?有没有更好的方法来处理这些情况?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-03 15:59:30

UpdateSourceTrigger属性的默认值是TextBoxLostFocus,这就是为什么在将焦点从textbox移到另一个控件(在您的情况下,单击按钮)之前不会更新ViewModel属性的原因。在绑定中将UpdateSourceTrigger的值设置为PropertyChanged

例如:

代码语言:javascript
运行
复制
<TextBox Name="ChannelSearch" 
         Text="{Binding Path=ChannelFilter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  
         TextChanged="ChannelSearch_TextChanged" />

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

对于最初的问题,您可以从doFilterChannels属性的setter调用viewModel方法(当然,不阻塞UI线程)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19163550

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档