【问题标题】:TextBox.Text OneWay Binding Not Responding to Code Behind ViewModel UpdateTextBox.Text 单向绑定不响应 ViewModel 更新背后的代码
【发布时间】:2013-05-26 11:17:33
【问题描述】:

我目前正在为我的 View 实现一个搜索(更准确地说是“过滤器”)表单,它使用 ApplicationBarIconButtons 来驱动用户与表单的交互:一个搜索按钮用于转换到 VisualState 并显示表单,一个用于清除当前过滤字符串值。接受过滤器的文本框绑定到 ViewModel 上的一个属性:

XAML

<toolkit:PhoneTextBox x:Name="txtSearch" Text="{Binding VisitsFilter, Mode=OneWay}" />

视图模型

private string _visitsFilter;
public string VisitsFilter
{
    get
    {
        return _visitsFilter;
    }
    set
    {
        _visitsFilter = value;
        RaisePropertyChanged("VisitsFilter");
        RebuildVisits();
    }
}

问题是 ApplicationBarIconButtons 并没有任何能力使用命令或类似的方法绑定到我的 ViewModel 上的点,因此我在其 Click 事件的处理程序后面的代码中处理它们与它的交互。看起来应该没什么大不了的......从页面的数据上下文中获取 ViewModel 并设置绑定属性的值:

代码背后

private VisitsViewModel ViewModel
{
    get
    {
        return this.DataContext as VisitsViewModel;
    }
}

private void abbClear_Click(object sender, EventArgs e)
{
    this.Focus();
    ViewModel.VisitsFilter = string.Empty;
}

如果您通过 setter 遵循上面的代码,您会看到我设置了私有字符串成员的值,然后引发属性已更改的事件。实际上,我的视图中有一个订阅此事件的代码,该代码正在执行有关使“清除”按钮可见或不可见的其他逻辑,但关键是它正在成功侦听该事件。但是,上面标记中的 OneWay 绑定不会更新我的 PhoneTextBox 上 Text 属性的值。

这里的断开连接在哪里?

【问题讨论】:

  • 你能分享一个小的复制样本吗? OneWay 绑定是默认设置,如果 DataContext 和您的通知功能(在您的情况下为 RaisePropertyChanged)工作,那么它应该没问题。
  • 具有讽刺意味的是,我复制一个小示例的尝试与原始代码一样失败了。我会去评论一些点点滴滴,看看有什么事情发生了,当我再次访问它并回复你。

标签: mvvm windows-phone-8 windows-phone mvvm-light


【解决方案1】:
  1. 可能是您的 setter 中的方法花费的时间太长,或者执行的操作可能会干扰 UI 线程。这意味着当它发布以响应您的 PropertyChanged 时,它错过了更新的机会......

尝试删除 RebuildVisits();从二传手。如果可行,并且这个假设是正确的,则在不同的线程上执行 RebuildVisits。

public string VisitsFilter
{
  get { return _visitsFilter; }
  set { 
         _visitsFilter = value;
         RaisePropertyChanged("VisitsFilter");

         Tasks.StartNew (() => { RebuildVisits();});
       }
    ....

}

2.如果它确实是一种单向绑定,会干扰您的更新。为什么不设置 TextBox

IsReadOnly = "真" 并将绑定设置为 TwoWay

【讨论】:

  • 那会很有趣。看起来你的第一次猜测走在了正确的轨道上。看起来我将不得不将我的 RaisePropertyChanged 调用编组回调用线程。
  • 看起来重建运行时间不长,它干扰了 UI 线程(它实际上只是使用内存中的集合并根据在文本框中输入的内容对其进行过滤)。我没有将文本框设置为只读,因为只有在有人在搜索框中键入内容并点击 Enter 按钮来调用搜索时,后面的 ViewModel 才会更新,这会将值写入 ViewModel。
  • 是的(评论 1),当我经常不得不做同样的事情,当我从不同的线程处理完某些东西时,这是有道理的。我有一个静态实用程序方法,可以检查对主 UI 线程的访问并发送... Utilities.OnUI(() => VisitFilter = 3);
猜你喜欢
  • 2012-07-20
  • 2010-11-10
  • 2015-03-21
  • 2016-11-03
  • 2017-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-18
相关资源
最近更新 更多