在MVVM中绑定WPF线程绑定访问错误
所以我想将WPF的动态数据显示合并到我的MVVM caliburn项目中(如果有人希望测试此动态数据显示,我正在使用LineChart控件)错误)。有一个LineChart绑定到ObservableCollection。只有在具有LineChart的控件的代码集合中进行收集时才有效。如果尝试绑定到集合ViewModel,则依赖项属性会引发InvalidOperationException。这个问题怎么解决?在MVVM中绑定WPF线程绑定访问错误
我已经看到,当你改变属性绑定到的集合并知道修复方法时,会发生这种情况,但绝不会在绑定的实际过程中发生。我已经尝试在调度程序调用中创建集合(就像你要添加或删除一样),但它没有帮助。
编辑:正如我在第二段中所述,异常不在更改集合。它是在约束点提出的。更重要的是,我试图使用other question中的解决方案,但他们没有帮助。
编辑#2:异常消息是“调用线程不能访问此对象,因为不同的线程拥有它”。人们总是告诉我解决方案的集合变化,但它甚至没有得到改变。它在绑定阶段失败(ItemsSource =“{binding collection}”in xaml)。
编辑#3:我仔细检查并注意到ViewModel是在UI线程中创建的,这只会产生更多问题。
好吧,我花了很长时间才找到问题的根源。
与别人所怀疑的不同,这根本不是多线程问题。
相反,这是您正在使用的DynamicDataDisplay
库的问题。
有一个明确的理由,为什么你ListBox
对象上的ItemsSource
绑定工作,并且不会对Chart
(的Microsoft.Research.DynamicDataDisplay.Markers2.LineChart
型)工作:Chart
既不具有可视化,也不是一个逻辑父。
您可以检查这个,如果你将以下代码插入到Button_Click
后他们设置一个断点:
var visualParent = VisualTreeHelper.GetParent(Chart);
var logicalParent1 = Chart.Parent;
var logicalParent2 = LogicalTreeHelper.GetParent(Chart);
你可以看到,他们都是null
。
因此,您在LineChart.ItemsSourceProperty
上设置的Binding
与Path=ExampleCollection
找不到任何源值,并且只将null
分配给ItemsSource
。这是因为DataContext
是从父级继承的 - 但是当没有父级时,则不会有任何DataContext
继承。
而且因为Chart
不是视觉或逻辑树的一部分,所以没有(容易)任何绑定到外部DataContext
甚至可以工作。
要验证DataContext
是null
刚加入这一行前面的代码:
var dataContext = Chart.DataContext;
现在有这三种可能的解决方案。
首先,您可以使用下面的代码手动继承Window
的DataContext
:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// Just add the following line.
Chart.DataContext = DataContext;
Chart.StrokeThickness = 3;
Chart.SetBinding(LineChart.ItemsSourceProperty, new Binding("ExampleCollection"));
// ...
}
如果您只需添加这一条线,你会看到你的其他的多线程代码工作得很好,图表用某种正弦波模式更新。
二,作为另一种可能的解决方案,你可以咨询为DynamicDataDisplay
库中的文件和检查正确的和预期的方式来分配ItemsSource
到LineChart
使用数据绑定。
我试图自己搜索文档,甚至在两个小时左右的时间内从该库中调试了大量代码,但是文档几乎不存在,代码太复杂,无法在几个小时内完全理解。我尝试使用几种工具(Visual Studio Live Visual Tree,Snoop,...)来显示ChartPlotter
的可视化树,但每次都得到*Exception
,所以本库中的某些内容是有缺陷的。
三,你可以使用一个Resource
作为一种代理对象的创建“结合桥梁”的MainWindowViewModel
的同一个实例。
对于这个工作,你必须做这样的事情在这里建议:Data binding outside the visual tree. Data Context bridging
底线:所以,如果你只想把工作做好,我将设置DataContext
代码如上所示。 (特别是如果DataContext
中的ViewModel
的实例永远不会改变。)
如果您想要使用纯数据绑定,那么我可能会使用“绑定桥”或搜索另一个支持此方案的图表库。
非常感谢您提供的所有帮助和翔实的答案/评论! –
@PaulVinogradov非常欢迎您!很高兴我能帮助你! :-) – haindl
可能的[ObservableCollection和线程]重复(http://*.com/questions/2293246/observablecollection-and-threading) – dymanoid
如果你可以发布'StackTrace'或至少是'Message'你的'InvalidOperationException'。 – haindl
@haindl我的不好,加了吧 –