【发布时间】:2012-07-22 02:33:49
【问题描述】:
假设我的屏幕上有一个部分正在编辑“当前记录”。所以我的视图模型有一个包含所有当前编辑属性的类,例如:
class Record {
public string Notes { get { return "Foo"; } set { _notes = value; Notify("Notes"); }
}
我们将这个类添加到视图模型中:
class AdjustsmentViewModel {
public Record CurrentRecord { get { return new Record(); }}
}
如何在我的视图中绑定到 CurrentRecord 的 Notes 属性?我试过这个:
<TextBox Text="{Binding CurrentRecord.Notes, Mode=TwoWay}" VerticalScrollBarVisibility="Auto" TextWrapping="WrapWithOverflow" AcceptsReturn="True" />
但这不起作用。我还尝试设置周围 StackPanel 的 DataContext:
<StackPanel DataContext="{Binding CurrentRecord}">
之后,我尝试在我的 TextBox {Binding Notes} 和 {Binding Path=Notes} 中,但这些似乎都不起作用。
也许上面真的应该工作,我在别处搞砸了?
更新
这发生在用户控件中。这个用户控件有一个独立的视图模型,来自它的父窗口。
this.DataContext = UnityUtil.Resolve<AdjustmentsViewModel>();
我还看到一个绑定错误:'Notes' property not found on 'object'''MainViewModel'
该视图模型设置在主窗口上。
为了验证我是否绑定了正确的 ViewModel,我只是直接在 viewmodel 上添加了这个属性:
public string Notes2 { get { return "Bar"; } }
以及视图中对应的文本块:
<TextBlock Text="{Binding Path=Notes2}" />
这按预期工作。
大获成功
感谢 Ryan,我能够找到问题所在。它不在属性本身,而是在设置 CurrentRecord 的方式。在我的设置器中,我调用了 INotifyPropertyChange 处理程序,但其中包含属性的旧名称。所以视图没有收到 CurrentRecord 通知,所以我猜 Notes 通知是不够的 ..
总之,这个表示法是正确的:{Binding Path=CurrentRecord.Notes}
【问题讨论】:
-
您遇到的错误是什么?
-
没有错误。我只是在文本框中看不到值(我的默认 Foo 字符串)
-
您的观点是什么...一个窗口、一个用户控件、一个数据模板?您如何将视图的数据上下文设置为视图模型对象?
-
您需要解决的一件事是,如果您想要双向绑定,您需要为您的 Notes 属性设置一个“setter”。
-
是的,这是使用字符串作为通知属性已更改的机制的一个缺点。我认为一些 MVVM 框架,例如PRISM,让您通过属性本身进行通知(我认为这反过来只是使用了一些反射)。很高兴你准备好了。