WPF Itemscontrol n 数据模板未正确显示
WPF Itemcontrol and datatemplate do not show properly
我在使用 ItemControl、DataTemplate 和 Visifire 图表时遇到问题。
首先,XAML中的代码如下
<DataTemplate x:Key="markerChartTemplate">
<vc:Chart Height="200" Theme="Theme1" Style="{StaticResource ChartStyle}">
<vc:Chart.Series>
<vc:DataSeries RenderAs="Line" LightWeight="true" ShadowEnabled="false" LightingEnabled="false" MarkerSize="4" LineThickness="1" DataPoints="{Binding _xAxisCollection}" />
<vc:DataSeries RenderAs="Line" LightWeight="true" ShadowEnabled="false" LightingEnabled="false" MarkerSize="4" LineThickness="1" DataPoints="{Binding _yAxisCollection}" />
<vc:DataSeries RenderAs="Line" LightWeight="true" ShadowEnabled="false" LightingEnabled="false" MarkerSize="4" LineThickness="1" DataPoints="{Binding _zAxisCollection}" />
</vc:Chart.Series>
</vc:Chart>
</DataTemplate>
<ScrollViewer HorizontalScrollBarVisibility="Disabled" HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto">
<ItemsControl VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ItemsSource="{Binding Path=_markerChartsCollections}" ItemTemplate="{StaticResource markerChartTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
_markerChartsCollections
定义为
public ObservableCollection<My3DLineChartObject> _markerChartsCollections
在 ViewModel 和 Model 中。
现在,在模型中,我初始化两个 My3DLineChartObject
对象并将其放入 _markerChartsCollections
。
结果是我可以看到两个,与_markerChartsCollections 中的My3DLineChartObject 编号相同。但是,My3DLineChartObject中的属性,包括_xAxisCollection、_yAxisCollection和_zAxisCollection,无法显示。
谁能帮忙看看可能是什么原因?
输出信息为
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\windows\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework.Aero2\v4.0_4.0.0.0__31bf3856ad364e35\PresentationFramework.Aero2.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\windows\Microsoft.Net\assembly\GAC_32\Microsoft.Kinect\v4.0_2.0.0.0__31bf3856ad364e35\Microsoft.Kinect.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\Users\admin\Desktop\Hand\SkeletonMarkerCapture_Good_2\SkeletonMarkerCapture\bin\Debug\AForge.Imaging.dll'. Cannot find or open the PDB file.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\Users\admin\Desktop\Hand\SkeletonMarkerCapture_Good_2\SkeletonMarkerCapture\bin\Debug\Emgu.CV.dll'. Module was built without symbols.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\Users\admin\Desktop\Hand\SkeletonMarkerCapture_Good_2\SkeletonMarkerCapture\bin\Debug\Emgu.Util.dll'. Module was built without symbols.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\Users\admin\Desktop\Hand\SkeletonMarkerCapture_Good_2\SkeletonMarkerCapture\bin\Debug\AForge.dll'. Cannot find or open the PDB file.
The thread 0x75d4 has exited with code 259 (0x103).
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\windows\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework-SystemXmlLinq\v4.0_4.0.0.0__b77a5c561934e089\PresentationFramework-SystemXmlLinq.dll'. Cannot find or open the PDB file.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\windows\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework-SystemXml\v4.0_4.0.0.0__b77a5c561934e089\PresentationFramework-SystemXml.dll'. Cannot find or open the PDB file.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\Users\admin\Desktop\Hand\SkeletonMarkerCapture_Good_2\SkeletonMarkerCapture\bin\Debug\GalaSoft.MvvmLight.dll'. Symbols loaded.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\windows\Microsoft.Net\assembly\GAC_MSIL\UIAutomationTypes\v4.0_4.0.0.`enter code here`0__31bf3856ad364e35\UIAutomationTypes.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
我在下面包含了我的原始答案中的评论,但是在使用了 Visifire 之后,您实际上 运行 可能会遇到库设计方面的问题(我从几年前使用它)。图表上公开的许多 DependencyProperties 无法绑定。我制定了一个像您这样的示例并 post 编辑了它 here。具体来说,与数据点的绑定是在内部管理的。你真正想要的是绑定数据源。您还需要设置 YValue 映射 ,即使您在 ViewModel 中使用它们的 DataPoint 类型。
例如,您的 DataTemplate 需要更像这样绑定您的点集合
<DataTemplate x:Key="MarkerChartTemplate">
<vc:Chart Height="200" Width="400">
<vc:Chart.Series>
<vc:DataSeries RenderAs="Line" DataSource="{Binding XAxisCollection}">
<vc:DataSeries.DataMappings>
<vc:DataMapping MemberName="YValue" Path="YValue"/>
</vc:DataSeries.DataMappings>
</vc:DataSeries>
</vc:Chart.Series>
</vc:Chart>
</DataTemplate>
您应该查看 Visifire docs 了解更多详情。不幸的是,文档并没有明确说明其他 DependencyProperty 更新在库中无效。
您应该检查的其他事项和一般良好做法:
您似乎在尝试使用 Visifire 图表来显示 3 系列图表的 ItemsControl。有很多事情可能会出错。这是我建议看的内容。
首先,检查您的绑定是否有效。也许你忘了做点什么 public。也许您的系列没有显示,因为它们没有通知属性,并且您在最初绑定时没有设置它们。拥有一个复杂的 DataTemplate 一开始只会让事情变得混乱,所以尝试一些更简单的东西,比如
<DataTemplate x:Key="SimplerTemplate">
<UniformGrid Columns="3">
<TextBlock Text="{Binding _xAxisCollection}"/>
<TextBlock Text="{Binding _yAxisCollection}"/>
<TextBlock Text="{Binding _zAxisCollection}"/>
</UniformGrid>
</DataTemplate>
假设您这样做并且在每个 TextBlock 中看到一个字符串对应于 Visifire.Charts.DataPointCollection。那太棒了。这意味着您的 DataBinding 将真正起作用。在这种情况下,我会 post 更多关于您如何定义 DataSeries 的示例代码,以便更熟悉 Visifire 的人可以提供帮助(在这种情况下您也应该标记 Visifire)。
但是,假设它不起作用。您可以从 Visual Studio(您的输出 window)中检查一件有用的事情。还有一些方法可以让您的程序更容易调试。
- 检查您的控制台输出是否有 System.Windows.Data 绑定错误。如果有拼写错误或您的字段不可访问,WPF 将记录相关错误。
- 不要绑定到原始字段。使您的 ObservableCollections 私有且只读。用 getter 包裹它们。您要确保 none 的其他代码,尤其是 XAML 中定义的 DataBindings 在幕后将您的集合交换出去。使用 TwoWay 绑定,不难犯这种错误。
- 在 My3DLineChartObject 上 - 同样的事情,用 getter 属性包装你的三个系列并绑定到那些。
- 在您的 ViewModel 和 My3DLineChartObject 上实施 INotifyPropertyChanged。每当您更改 My3DLineChartObject 中的系列字段之一时,您还需要引发 NotifyPropertyChanged("...AxisCollection")。如果您从不更改它们,则应将它们设置为只读并仅提供 getter。同样,这避免了它们被 TwoWay 绑定换出。
- 在您的 AxisCollection getter 中放置断点。当您 运行 您的应用程序并显示此视图时,那些 getter 会被调用吗?数据绑定使用反射,它将调用您的 getter 属性。
希望对您有所帮助。
我在使用 ItemControl、DataTemplate 和 Visifire 图表时遇到问题。
首先,XAML中的代码如下
<DataTemplate x:Key="markerChartTemplate">
<vc:Chart Height="200" Theme="Theme1" Style="{StaticResource ChartStyle}">
<vc:Chart.Series>
<vc:DataSeries RenderAs="Line" LightWeight="true" ShadowEnabled="false" LightingEnabled="false" MarkerSize="4" LineThickness="1" DataPoints="{Binding _xAxisCollection}" />
<vc:DataSeries RenderAs="Line" LightWeight="true" ShadowEnabled="false" LightingEnabled="false" MarkerSize="4" LineThickness="1" DataPoints="{Binding _yAxisCollection}" />
<vc:DataSeries RenderAs="Line" LightWeight="true" ShadowEnabled="false" LightingEnabled="false" MarkerSize="4" LineThickness="1" DataPoints="{Binding _zAxisCollection}" />
</vc:Chart.Series>
</vc:Chart>
</DataTemplate>
<ScrollViewer HorizontalScrollBarVisibility="Disabled" HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto">
<ItemsControl VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ItemsSource="{Binding Path=_markerChartsCollections}" ItemTemplate="{StaticResource markerChartTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
_markerChartsCollections
定义为
public ObservableCollection<My3DLineChartObject> _markerChartsCollections
在 ViewModel 和 Model 中。
现在,在模型中,我初始化两个 My3DLineChartObject
对象并将其放入 _markerChartsCollections
。
结果是我可以看到两个,与_markerChartsCollections 中的My3DLineChartObject 编号相同。但是,My3DLineChartObject中的属性,包括_xAxisCollection、_yAxisCollection和_zAxisCollection,无法显示。
谁能帮忙看看可能是什么原因?
输出信息为
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\windows\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework.Aero2\v4.0_4.0.0.0__31bf3856ad364e35\PresentationFramework.Aero2.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\windows\Microsoft.Net\assembly\GAC_32\Microsoft.Kinect\v4.0_2.0.0.0__31bf3856ad364e35\Microsoft.Kinect.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\Users\admin\Desktop\Hand\SkeletonMarkerCapture_Good_2\SkeletonMarkerCapture\bin\Debug\AForge.Imaging.dll'. Cannot find or open the PDB file.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\Users\admin\Desktop\Hand\SkeletonMarkerCapture_Good_2\SkeletonMarkerCapture\bin\Debug\Emgu.CV.dll'. Module was built without symbols.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\Users\admin\Desktop\Hand\SkeletonMarkerCapture_Good_2\SkeletonMarkerCapture\bin\Debug\Emgu.Util.dll'. Module was built without symbols.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\Users\admin\Desktop\Hand\SkeletonMarkerCapture_Good_2\SkeletonMarkerCapture\bin\Debug\AForge.dll'. Cannot find or open the PDB file.
The thread 0x75d4 has exited with code 259 (0x103).
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\windows\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework-SystemXmlLinq\v4.0_4.0.0.0__b77a5c561934e089\PresentationFramework-SystemXmlLinq.dll'. Cannot find or open the PDB file.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\windows\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework-SystemXml\v4.0_4.0.0.0__b77a5c561934e089\PresentationFramework-SystemXml.dll'. Cannot find or open the PDB file.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\Users\admin\Desktop\Hand\SkeletonMarkerCapture_Good_2\SkeletonMarkerCapture\bin\Debug\GalaSoft.MvvmLight.dll'. Symbols loaded.
'SkeletonMarkerCapture.vshost.exe' (CLR v4.0.30319: SkeletonMarkerCapture.vshost.exe): Loaded 'C:\windows\Microsoft.Net\assembly\GAC_MSIL\UIAutomationTypes\v4.0_4.0.0.`enter code here`0__31bf3856ad364e35\UIAutomationTypes.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
我在下面包含了我的原始答案中的评论,但是在使用了 Visifire 之后,您实际上 运行 可能会遇到库设计方面的问题(我从几年前使用它)。图表上公开的许多 DependencyProperties 无法绑定。我制定了一个像您这样的示例并 post 编辑了它 here。具体来说,与数据点的绑定是在内部管理的。你真正想要的是绑定数据源。您还需要设置 YValue 映射 ,即使您在 ViewModel 中使用它们的 DataPoint 类型。
例如,您的 DataTemplate 需要更像这样绑定您的点集合
<DataTemplate x:Key="MarkerChartTemplate">
<vc:Chart Height="200" Width="400">
<vc:Chart.Series>
<vc:DataSeries RenderAs="Line" DataSource="{Binding XAxisCollection}">
<vc:DataSeries.DataMappings>
<vc:DataMapping MemberName="YValue" Path="YValue"/>
</vc:DataSeries.DataMappings>
</vc:DataSeries>
</vc:Chart.Series>
</vc:Chart>
</DataTemplate>
您应该查看 Visifire docs 了解更多详情。不幸的是,文档并没有明确说明其他 DependencyProperty 更新在库中无效。
您应该检查的其他事项和一般良好做法:
您似乎在尝试使用 Visifire 图表来显示 3 系列图表的 ItemsControl。有很多事情可能会出错。这是我建议看的内容。
首先,检查您的绑定是否有效。也许你忘了做点什么 public。也许您的系列没有显示,因为它们没有通知属性,并且您在最初绑定时没有设置它们。拥有一个复杂的 DataTemplate 一开始只会让事情变得混乱,所以尝试一些更简单的东西,比如
<DataTemplate x:Key="SimplerTemplate">
<UniformGrid Columns="3">
<TextBlock Text="{Binding _xAxisCollection}"/>
<TextBlock Text="{Binding _yAxisCollection}"/>
<TextBlock Text="{Binding _zAxisCollection}"/>
</UniformGrid>
</DataTemplate>
假设您这样做并且在每个 TextBlock 中看到一个字符串对应于 Visifire.Charts.DataPointCollection。那太棒了。这意味着您的 DataBinding 将真正起作用。在这种情况下,我会 post 更多关于您如何定义 DataSeries 的示例代码,以便更熟悉 Visifire 的人可以提供帮助(在这种情况下您也应该标记 Visifire)。
但是,假设它不起作用。您可以从 Visual Studio(您的输出 window)中检查一件有用的事情。还有一些方法可以让您的程序更容易调试。
- 检查您的控制台输出是否有 System.Windows.Data 绑定错误。如果有拼写错误或您的字段不可访问,WPF 将记录相关错误。
- 不要绑定到原始字段。使您的 ObservableCollections 私有且只读。用 getter 包裹它们。您要确保 none 的其他代码,尤其是 XAML 中定义的 DataBindings 在幕后将您的集合交换出去。使用 TwoWay 绑定,不难犯这种错误。
- 在 My3DLineChartObject 上 - 同样的事情,用 getter 属性包装你的三个系列并绑定到那些。
- 在您的 ViewModel 和 My3DLineChartObject 上实施 INotifyPropertyChanged。每当您更改 My3DLineChartObject 中的系列字段之一时,您还需要引发 NotifyPropertyChanged("...AxisCollection")。如果您从不更改它们,则应将它们设置为只读并仅提供 getter。同样,这避免了它们被 TwoWay 绑定换出。
- 在您的 AxisCollection getter 中放置断点。当您 运行 您的应用程序并显示此视图时,那些 getter 会被调用吗?数据绑定使用反射,它将调用您的 getter 属性。
希望对您有所帮助。