【问题标题】:Wpf text box not updated from view modelWpf 文本框未从视图模型更新
【发布时间】:2012-06-15 16:12:53
【问题描述】:

我的视图模型中有一个属性,它在某些条件下返回一个常量。

实现方式与此类似:

    class Tmp : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public String Text
        {
            get { return "testing"; }
            set
            {
                PropertyChanged(this,new PropertyChangedEventArgs("Text"));                }
        }
    }

所以属性 Text 总是返回“测试”。

我将它绑定到一个文本框,例如:

  <TextBox Text="{Binding Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

当应用程序启动时,文本框 correclty 显示正在测试。

现在,当我在文本框中键入内容时,将调用 setter,它调用 PropertyChanged。

在此之后(可能是 GUI)调用 getter 并获取值“testing”。

但是文本框中的文本并没有变回测试。

所以我可以在文本框中输入“abc”,即使模型只是存储“测试”,文本框也会显示“abc”。

为什么每次击键时文本框中的文本没有重置为“测试”?

【问题讨论】:

  • IIRC 你不必通过 propertychanged 事件而不是空字符串来传递属性名称吗?
  • 不是真正的 String.Empty 或 "" 表示“嘿,我的所有属性都无效,请全部获取”在这种情况下,它的意思是“也获取文本”......它太多了,但工作.
  • Empty sting 应该强制所有内容都得到更新。我原本的属性名 .. 改为 "" 以防万一
  • 更改了代码但仍然得到相同的行为
  • 我刚试过这个(.NET 4.5),它按你的预期工作

标签: c# wpf binding


【解决方案1】:

为什么文本框要再次获取文本?它只是将它写入您的源属性,它“知道”它必须相同,因为他正在告诉属性新值。否则,您将创建循环引用。您正在做的事情完全违背了物业所期望的准则和行为。

删除setter,以一种方式绑定,在常量更改时提高文本属性,并使文本框只读。请记住,不必在 setter 中调用 Propertychanged。

要使您的初始方法有效,您需要打破“文本框更改属性但不会监听传入的提升”状态

set
{
   sUIDispatcher.BeginInvoke((Action)(() => Raise("Name")));
}

我想补充一点,这是一个非常糟糕的主意,强烈建议您不要这样做。

【讨论】:

  • 这是原始问题的简化版本,因此我无法进行单向绑定。我可能会禁用文本框,但这将涉及重大重构或多转换器。
  • 我认为它会起作用的原因是因为有些东西正在调用我的吸气剂。由于在此示例中除了文本框之外还有注释,我认为文本框正在读取“文本”属性
  • 就像我说的那样,它确实会读取 text 属性。但是当它因为在文本框中输入的文本而更新时,它会“禁用”监听提升,因为他预计下一个传入的提升将正是文本框告诉属性的内容。请参阅我的答案,我添加了一个代码 sn-p,它的工作方式可能像您想要的那样。
  • 我已经在做一个替代实现来摆脱这个问题。我只是出于好奇问了这个问题。感谢您解释这个问题。我自己永远也想不通。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-10
  • 2019-01-19
  • 2012-10-03
相关资源
最近更新 更多