(连续8小时拔头发后,我已经放弃了。如果有人可以来拯救,我将非常感激):
这就是我所拥有的:
AlbumItem :这是一个ItemsControl
,它使用Canvas
作为其ItemsPanel
并绑定到底层VM的集合属性。在此控件的DataTemplate
部分中定义的少数Resources
执行ViewModel对象到UI对象的转换。这种控制非常好,并且符合预期。
相册:这又是一个ItemsControl
,它使用UniformGrid
作为其ItemsPanel
并绑定到底层VM的集合属性。此控件显示AlbumItem
s的网格。我已将此控件的ItemTemplate
设置为AlbumItem
。
无论我做什么,第二个控件都不会使用其ItemTemplate
来显示其项目。 UniformGrid
效果很好,我得到一个3 x 3网格的项目,但每个项目都是一个简单的TextBlock
,显示了底层VM对象的类名。
我也尝试使用DataTemplate
,而不是使用ItemTemplate
,但无济于事。
任何人都可以看到哪里出错了?
发布工作样本将是一项艰巨的任务(这是一个复杂的项目),但我可以在这里发布相关的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
也是如此。当我钻研ItemsSource
时,我实际上可以看到Snoop中的所有VM对象。ItemTemplate
和/或ItemsPanel
属性,我会以网格或列表的形式看到所有项目(即带有类名的TextBlock),具体取决于属性我重置了。答案 0 :(得分:0)
我已经尝试编写模仿代码的最小项目 - 我猜我遇到了和你一样的问题,我的AlbumItem虚拟机也有了TextBlocks。
对我而言,我正努力在ItemsControl.ItemTemplate
中使用AlbumItem
,但直接使用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放在可视(资源)树的较高位置,看看会发生什么。
答案 1 :(得分:0)
原来这是由于底层数据源。我使用self.task_xml = "<?xml version="1.0" encoding="utf-8"?>
<django-objects version="1.0">
<object model="task.task" pk="31">
<field name="name" type="CharField">New Task</field>
<field name="parent_task_id" type="IntegerField">0</field>
</object>
<object model="task.task" pk="32">
<field name="name" type="CharField">New Task</field>
<field name="parent_task_id" type="IntegerField">0</field>
</object>
<object model="task.task" pk="33">
<field name="name" type="CharField">New Task</field>
<field name="parent_task_id" type="IntegerField">31</field>
</object>
<object model="task.task" pk="34">
<field name="name" type="CharField">New Task</field>
<field name="parent_task_id" type="IntegerField">31</field>
</object>
</django-objects>"
58 self.xmlData = ET.fromstring(self.task_xml)
59
60 self.task_list = []
61 taskList = []
62 for obj in self.xmlData.iter("object"):
63 parent_task_id = obj.find("field[@name='parent_task_id']").text
64 if parent_task_id == EMPTY_UUID:
65 task = TaskViewModel()
66 task.id = obj.get("pk")
67 task.name = obj.find("field[@name='name']").text
68 task.parent_task_id = parent_task_id
69 taskList.append(task)
70 # Apprend taskList:
71 for task in taskList:
72 taskViewModel = TaskViewModel(task.id, True)
73 self.task_list.append(taskViewModel)
绑定了相册,由于基础属性List<T>
的以下行,因此无法更新其项目中的更改:
Baked
这是If _Baked Is value Then Return
属性设置器中的第一行(我使用MVVM Light提供的默认属性模板)。由于我从未将新Baked
分配给List<T>
;只更改了其中的项目,上述行将停止提升属性更改通知。一旦我解决了这个问题,我的专辑开始填充。