我的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。我很想知道控件/窗口生命周期中绑定发生的时间点,以及是否有其他方法强制绑定发生?
提前致谢 安迪
答案 0 :(得分:1)
为了理解绑定的转移方式,您需要了解Dispatcher
。基本上,它是一个优先级队列。布局,绑定,渲染,输入等内容以不同的优先级放置在队列中。
现在,从它的声音,你永远不会让执行回到Dispatcher
。这意味着Binding
值无法传输(当您手动调用UpdateTarget
时,您只是在Dispatcher
上安排此值)。因此,简而言之,您需要让Dispatcher
在完成初始化之前执行排队操作。
执行此操作的最简单方法是在方法的较低BeginInvoke
上调用DispatcherPriority
以完成初始化。由于布局系统的工作方式的性质,有时候选择正确的优先级可能会很棘手,但如果你选择DispatcherPriority.Loaded
,你可能会没事。
答案 1 :(得分:0)
我的建议是拥有一个View Models实现的界面,它会公开Id属性。然后,您可以让桌面管理器通过将其转换为适当的接口从DataContext中获取Id。这可能是一个更清晰的责任分离,因为您的桌面管理器可能应该尽可能少地了解具体的视图(为了可测试性)。