ItemsControl中的ItemsControl

时间:2015-09-15 13:38:13

标签: .net wpf xaml datatemplate itemscontrol

连续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对象。
  • 默认情况下,相册根本不显示任何内容。如果我使用Snoop重置专辑的ItemTemplate和/或ItemsPanel属性,我会以网格或列表的形式看到所有项目(即带有类名的TextBlock),具体取决于属性我重置了。
  • AlbumItem适用于设计时XML数据。专辑没有。

2 个答案:

答案 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>;只更改了其中的项目,上述行将停止提升属性更改通知。一旦我解决了这个问题,我的专辑开始填充。

相关问题