我有一个主视图绑定到这样的子视图(支持属性类型为object
):
<ContentControl Content="{Binding WalletsView}"/>
现在,我已经为相应的viewmodel添加了另一个属性,即
public SmartObservableCollection<Selectable<Type>> PriceGrabbers {get; private set;}
其中SmartObservableCollection
派生自ObservableCollection
,以简化多线程更新。
现在我得到了很多绑定错误(事实上,在子视图模型中运行调试窗口的所有绑定)就像这样(有趣的是,如果我再次删除PriceGrabbers
属性,所有错误都消失了):
System.Windows.Data错误:40:BindingExpression路径错误:'对象'''MainWindowViewModel'(HashCode = 30986197)'上找不到'OverviewHidden'属性。 BindingExpression:路径= OverviewHidden; DataItem ='MainWindowViewModel'(HashCode = 30986197); target元素是'ColumnDefinition'(HashCode = 22768693); target属性是'NoTarget'(类型'Object')
因此,绑定引擎会尝试在主视图模型上查找任何和所有绑定。 绑定工作完全正常。虽然这没关系,但我宁愿错误消失。你们有没有遇到过这个问题,如果是的话,你是怎么解决的?
答案 0 :(得分:0)
问题不在于WPF,而在于我将MEF用作组合容器。该属性修改类的导入顺序,并且首先将与MainWIndow相对应的ViewModel分配给所有视图,然后分配正确的视图。刷新数据上下文时,将更新所有绑定,从而使应用程序正常工作。
编辑,现在我找到了完整的理由。
SmartObservableCollection
在Action<Action>>
事件上执行CollectionChanged
参数,这是必需的,因为我的大多数集合都以多线程方式更新,但事件必须在GUI线程,否则你会得到一个例外。
为此,我的观点将Dispatcher.Invoke()
和Dispatcher.BeginInvoke()
公开为方法,然后我将其提供给集合。
在启动时,DataContexts在基类ViewModel
中通过以下行分配:
Dispatcher.CurrentDispatcher.BeginInvoke((Action)delegate()
{
view.DataContext = this;
});
谁有想法?
这个hickup的原因很简单,我提供了Dispatcher.Invoke()
方法而不是Dispatcher.BeginInvoke()
到集合中。通过执行此操作(以及MainWindowViewModel
中使用的事实),它已在任何 DataContexts
分配给其他ViewModels
之前执行。
现在,下一步发生 - WPF引擎尝试绑定到子视图中的数据。当DataContext
为null
时,绑定引擎会向上移动可视树,直到找到一个设置的DataContext,在这种情况下,第一个集合DataContext位于MainWindowView
中,它是{{1} }。现在,在收集完成之后,调用所有其他操作并适当地分配DataContexts,从而重新执行绑定引擎,该子引擎在子视图上找到非null的DataContext并正确绑定。