WPF:绑定何时实际发生?

时间:2012-06-07 11:38:18

标签: wpf

我的MVVM应用程序有许多视图,这些视图继承自基本用户控件,该控件公开了“ID”属性。在XAML中,它绑定到视图底层视图模型上的ID属性,只需:

Id="{Binding Path=Id}"

视图模型实现了INotifyPropertyChanged,其ID在构造函数中设置。该ID用于唯一标识每个视图/视图模型,主要由“桌面管理器”用于管理主窗口内的用户控件,而非MDI应用程序。当我的应用程序启动时,我实例化各种视图模型及其视图,并将视图模型分配给视图'DataContext。然后我将视图传递给桌面管理器,将它们放在画布上,放置它们等等。

我遇到的问题是此时视图的ID仍为空,并且似乎只是稍后(当呈现UI时可能会?)绑定到数据上下文。我试图强制这样的绑定,但它没有帮助: -

var bindingExpression = widget.GetBindingExpression(DesktopElement.IdProperty);
bindingExpression.UpdateTarget();

这不是世界末日,因为我可以从视图模型中传递桌面管理器我的视图 ID,但感觉有点hacky。我很想知道控件/窗口生命周期中绑定发生的时间点,以及是否有其他方法强制绑定发生?

提前致谢 安迪

2 个答案:

答案 0 :(得分:1)

为了理解绑定的转移方式,您需要了解Dispatcher。基本上,它是一个优先级队列。布局,绑定,渲染,输入等内容以不同的优先级放置在队列中。

现在,从它的声音,你永远不会让执行回到Dispatcher。这意味着Binding值无法传输(当您手动调用UpdateTarget时,您只是在Dispatcher上安排此值)。因此,简而言之,您需要让Dispatcher在完成初始化之前执行排队操作。

执行此操作的最简单方法是在方法的较低BeginInvoke上调用DispatcherPriority以完成初始化。由于布局系统的工作方式的性质,有时候选择正确的优先级可能会很棘手,但如果你选择DispatcherPriority.Loaded,你可能会没事。

答案 1 :(得分:0)

我的建议是拥有一个View Models实现的界面,它会公开Id属性。然后,您可以让桌面管理器通过将其转换为适当的接口从DataContext中获取Id。这可能是一个更清晰的责任分离,因为您的桌面管理器可能应该尽可能少地了解具体的视图(为了可测试性)。