好吧,我花了很长时间才找到问题的根源。
与别人所怀疑的不同,这根本不是多线程问题。
相反,这是您正在使用的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
的可视化树,但每次都得到StackOverflowException
,所以本库中的某些内容是有缺陷的。
三,你可以使用一个Resource
作为一种代理对象的创建“结合桥梁”的MainWindowViewModel
的同一个实例。
对于这个工作,你必须做这样的事情在这里建议:Data binding outside the visual tree. Data Context bridging
底线:所以,如果你只想把工作做好,我将设置DataContext
代码如上所示。 (特别是如果DataContext
中的ViewModel
的实例永远不会改变。)
如果您想要使用纯数据绑定,那么我可能会使用“绑定桥”或搜索另一个支持此方案的图表库。
可能的[ObservableCollection和线程]重复(http://stackoverflow.com/questions/2293246/observablecollection-and-threading) – dymanoid
如果你可以发布'StackTrace'或至少是'Message'你的'InvalidOperationException'。 – haindl
@haindl我的不好,加了吧 –