ItemsControl 中的 ItemsControl
ItemsControl within ItemsControl
(连续拉了8个小时的头发,我已经放弃了,如果有人能来解救,将不胜感激):
这是我的:
AlbumItem:这是一个 ItemsControl
,它使用 Canvas
作为其 ItemsPanel
并绑定到一个集合 属性底层虚拟机。此控件的 Resources
部分中定义的少数 DataTemplate
执行将 ViewModel 对象转换为 UI 对象。此控件工作得非常好,符合预期。
专辑:这又是一个 ItemsControl
,它使用 UniformGrid
作为其 ItemsPanel
并绑定到一个集合 属性 底层虚拟机。此控件显示 AlbumItem
的网格。我已将此控件的 ItemTemplate
设置为 AlbumItem
。
无论我做什么,第二个控件都不会使用它的 ItemTemplate
来显示它的项目。 UniformGrid
效果很好,我得到了一个 3 x 3 的项目网格,但这些项目中的每一个都是一个简单的 TextBlock
显示基础 VM 对象的 class 名称。
我也尝试过使用 DataTemplate
,而不是使用 ItemTemplate
,但无济于事。
谁能看出哪里出了问题?
编辑
发布工作示例将是一项艰巨的任务(这是一个复杂的项目),但我可以在此处 post 相关 XAML:
AlbumItem
<ItemsControl x:Class="AlbumItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:bd="clr-namespace:ViewProject"
xmlns:vm="clr-namespace:ViewModelProject"
mc:Ignorable="d"
ItemsSource="{Binding Path=Children}"
ClipToBounds="True" Background="LightYellow">
<ItemsControl.Resources>
<BooleanToVisibilityConverter x:Key="B2VConverter" />
<DataTemplate DataType="{x:Type vm:Ellipse}">
<Ellipse IsHitTestVisible="False" StrokeThickness="{Binding BorderThickness}" Fill="{Binding Fill, Mode=OneWay}" Stroke="{Binding Stroke, Mode=OneWay}" />
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas HorizontalAlignment="Left" VerticalAlignment="Top" Focusable="true" Width="{Binding Size.Width}" Height="{Binding Size.Height}" FocusVisualStyle="{x:Null}">
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding Path=Location.X}" />
<Setter Property="Canvas.Top" Value="{Binding Path=Location.Y}" />
<Setter Property="Panel.ZIndex" Value="{Binding Path=GlobalZOrder}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
专辑
<ItemsControl x:Class="Album"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:bd="clr-namespace:ViewProject"
xmlns:vm="clr-namespace:ViewModelProject"
d:DesignHeight="500" d:DesignWidth="800"
ItemsSource="{Binding Drawing.Baked}"
ClipToBounds="True">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="3" Columns="3" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="vm:ReadonlyDrawingVM">
<bd:AlbumItem />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我已经使用 Snoop 确认以下内容:
- 相册的
DataContext
是正确的。它的 ItemsSource
也是如此。当我深入研究时,我实际上可以看到 Snoop 中的所有 VM 对象 ItemsSource
.
- 默认相册根本不显示任何内容。如果我使用 Snoop 重置 Album 的
ItemTemplate
and/or ItemsPanel
属性,我会看到网格形式的所有项目(即带有 class 名称的 TextBlock)或列表取决于我重置的 属性。
- AlbumItem 可以很好地处理设计时 XML 数据。相册没有。
我已经尝试编写模仿您的代码的尽可能小的项目 - 我想我遇到了与您相同的问题并且我的 AlbumItem VM 有 TextBlocks。
对我来说,我正在努力在 AlbumItem
中使用 ItemsControl.ItemTemplate
,但直接使用 - 而不是通过 ItemsControl.Resources
。经过一些实验,用于 AlbumItems 的 ContentPresenter 似乎无法找到 VM 的默认 DataTemplate。
<ItemsControl x:Class="so_wpf_32587588.AlbumItemView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:soWpf32587588="clr-namespace:so_wpf_32587588">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Width="100" Height="100" FocusVisualStyle="{x:Null}" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=X}"/>
<Setter Property="Canvas.Top" Value="{Binding Path=Y}"/>
<Setter Property="Panel.ZIndex" Value="{Binding ZOrder}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="soWpf32587588:AlbumItemView">
<Rectangle Width="40" Height="40" Fill="{Binding ItemBrush}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我在编写某种自定义 ResourceDictionary 时遇到了类似的问题 - 我发现字典已经被解析,但在 ResourceDictionary 使用的哈希中不可用,因此任何需要资源的控件都只获得默认资源而不是定义的资源。
您可以尝试将您的 DataTemplate 放在可视化(资源)树的较高位置,看看会发生什么。
原来是底层数据源的问题。我将相册与 List<T>
绑定,由于基础 属性 Baked
的以下行,它没有更新 UI 及其项目中的更改:
If _Baked Is value Then Return
这是 Baked
属性 setter 中的第一行(我使用的是 MVVM Light 提供的默认 属性 模板)。因为我从未将新的 List<T>
分配给 _Baked
;仅更改其中的项目,上面的行将停止 属性 更改通知被引发。一旦我解决了这个问题,我的相册就开始填充了。
(连续拉了8个小时的头发,我已经放弃了,如果有人能来解救,将不胜感激):
这是我的:
AlbumItem:这是一个 ItemsControl
,它使用 Canvas
作为其 ItemsPanel
并绑定到一个集合 属性底层虚拟机。此控件的 Resources
部分中定义的少数 DataTemplate
执行将 ViewModel 对象转换为 UI 对象。此控件工作得非常好,符合预期。
专辑:这又是一个 ItemsControl
,它使用 UniformGrid
作为其 ItemsPanel
并绑定到一个集合 属性 底层虚拟机。此控件显示 AlbumItem
的网格。我已将此控件的 ItemTemplate
设置为 AlbumItem
。
无论我做什么,第二个控件都不会使用它的 ItemTemplate
来显示它的项目。 UniformGrid
效果很好,我得到了一个 3 x 3 的项目网格,但这些项目中的每一个都是一个简单的 TextBlock
显示基础 VM 对象的 class 名称。
我也尝试过使用 DataTemplate
,而不是使用 ItemTemplate
,但无济于事。
谁能看出哪里出了问题?
编辑
发布工作示例将是一项艰巨的任务(这是一个复杂的项目),但我可以在此处 post 相关 XAML:
AlbumItem
<ItemsControl x:Class="AlbumItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:bd="clr-namespace:ViewProject"
xmlns:vm="clr-namespace:ViewModelProject"
mc:Ignorable="d"
ItemsSource="{Binding Path=Children}"
ClipToBounds="True" Background="LightYellow">
<ItemsControl.Resources>
<BooleanToVisibilityConverter x:Key="B2VConverter" />
<DataTemplate DataType="{x:Type vm:Ellipse}">
<Ellipse IsHitTestVisible="False" StrokeThickness="{Binding BorderThickness}" Fill="{Binding Fill, Mode=OneWay}" Stroke="{Binding Stroke, Mode=OneWay}" />
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas HorizontalAlignment="Left" VerticalAlignment="Top" Focusable="true" Width="{Binding Size.Width}" Height="{Binding Size.Height}" FocusVisualStyle="{x:Null}">
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding Path=Location.X}" />
<Setter Property="Canvas.Top" Value="{Binding Path=Location.Y}" />
<Setter Property="Panel.ZIndex" Value="{Binding Path=GlobalZOrder}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
专辑
<ItemsControl x:Class="Album"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:bd="clr-namespace:ViewProject"
xmlns:vm="clr-namespace:ViewModelProject"
d:DesignHeight="500" d:DesignWidth="800"
ItemsSource="{Binding Drawing.Baked}"
ClipToBounds="True">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="3" Columns="3" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="vm:ReadonlyDrawingVM">
<bd:AlbumItem />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我已经使用 Snoop 确认以下内容:
- 相册的
DataContext
是正确的。它的ItemsSource
也是如此。当我深入研究时,我实际上可以看到 Snoop 中的所有 VM 对象ItemsSource
. - 默认相册根本不显示任何内容。如果我使用 Snoop 重置 Album 的
ItemTemplate
and/orItemsPanel
属性,我会看到网格形式的所有项目(即带有 class 名称的 TextBlock)或列表取决于我重置的 属性。 - AlbumItem 可以很好地处理设计时 XML 数据。相册没有。
我已经尝试编写模仿您的代码的尽可能小的项目 - 我想我遇到了与您相同的问题并且我的 AlbumItem VM 有 TextBlocks。
对我来说,我正在努力在 AlbumItem
中使用 ItemsControl.ItemTemplate
,但直接使用 - 而不是通过 ItemsControl.Resources
。经过一些实验,用于 AlbumItems 的 ContentPresenter 似乎无法找到 VM 的默认 DataTemplate。
<ItemsControl x:Class="so_wpf_32587588.AlbumItemView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:soWpf32587588="clr-namespace:so_wpf_32587588">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Width="100" Height="100" FocusVisualStyle="{x:Null}" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=X}"/>
<Setter Property="Canvas.Top" Value="{Binding Path=Y}"/>
<Setter Property="Panel.ZIndex" Value="{Binding ZOrder}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="soWpf32587588:AlbumItemView">
<Rectangle Width="40" Height="40" Fill="{Binding ItemBrush}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我在编写某种自定义 ResourceDictionary 时遇到了类似的问题 - 我发现字典已经被解析,但在 ResourceDictionary 使用的哈希中不可用,因此任何需要资源的控件都只获得默认资源而不是定义的资源。
您可以尝试将您的 DataTemplate 放在可视化(资源)树的较高位置,看看会发生什么。
原来是底层数据源的问题。我将相册与 List<T>
绑定,由于基础 属性 Baked
的以下行,它没有更新 UI 及其项目中的更改:
If _Baked Is value Then Return
这是 Baked
属性 setter 中的第一行(我使用的是 MVVM Light 提供的默认 属性 模板)。因为我从未将新的 List<T>
分配给 _Baked
;仅更改其中的项目,上面的行将停止 属性 更改通知被引发。一旦我解决了这个问题,我的相册就开始填充了。