2015-08-03 29 views
4

有沒有辦法避免生成 ItemsControl包裹我的項目?我的ItemsControl綁定到VM屬性,我在ItemControl的資源中使用DataTemplate(不包含x:Key)來自定義集合對象的外觀。這一切都可以正常工作,但通過Snoop檢查顯示我所有的收集對象都被封裝在ContentPresenter之內,而不是直接添加到面板中。這個事實爲我創造了一些其他問題。有沒有辦法避免額外的包裝?避免ItemsControl中的ContentPresenter

這裏的XAML:

<ItemsControl ItemsSource="{Binding Path=Children}"> 
    <ItemsControl.Resources> 
    <DataTemplate DataType="{x:Type vm:Ellipse}"> 
     <Ellipse Fill="{Binding Fill}" Stroke="{Binding Stroke}" /> 
    </DataTemplate> 
    </ItemsControl.Resources> 
    <ItemsControl.ItemsPanel> 
    <ItemsPanelTemplate> 
     <Canvas Focusable="true" Margin="10" FocusVisualStyle="{x:Null}" /> 
    </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemContainerStyle> 
    <Style> 
     <Setter Property="Canvas.Left" Value="{Binding XLoc}" /> 
     <Setter Property="Canvas.Top" Value="{Binding YLoc}" /> 
     <Setter Property="Canvas.ZIndex" Value="{Binding ZOrder}" /> 
    </Style> 
    </ItemsControl.ItemContainerStyle> 
</ItemsControl> 
+0

您可能可以創建一個派生的ItemsControl並覆蓋[GetContainerForItemOverride](https://msdn.microsoft.com/en-us/library/aa346422(v = vs.110).aspx)方法來直接返回一個Ellipse控制。 – Clemens

+0

@Clemens:它不會期望我返回一個*容器*而不是實際的要顯示的項目(另一方面是由'DataTemplate'管理的)? – dotNET

+0

你不會再有DataTemplate了,否則你需要ContentPresenter。 – Clemens

回答

4

你可以創建一個派生的ItemsControl並覆蓋其GetContainerForItemOverride方法:

public class MyItemsControl : ItemsControl 
{ 
    protected override DependencyObject GetContainerForItemOverride() 
    { 
     return new Ellipse(); 
    } 
} 

你的ItemsControl的XAML將不設置ItemTemplate了,而且有一個ItemContainerStyle那直接瞄準橢圓:

<local:MyItemsControl ItemsSource="{Binding Items}"> 
    <local:MyItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Canvas/> 
     </ItemsPanelTemplate> 
    </local:MyItemsControl.ItemsPanel> 
    <local:MyItemsControl.ItemContainerStyle> 
     <Style TargetType="Ellipse"> 
      <Setter Property="Width" Value="100"/> 
      <Setter Property="Height" Value="100"/> 
      <Setter Property="Fill" Value="{Binding Fill}"/> 
      <Setter Property="Stroke" Value="{Binding Stroke}"/> 
      <Setter Property="Canvas.Left" Value="{Binding XLoc}"/> 
      <Setter Property="Canvas.Top" Value="{Binding YLoc}"/> 
      <Setter Property="Panel.ZIndex" Value="{Binding ZOrder}"/> 
     </Style> 
    </local:MyItemsControl.ItemContainerStyle> 
</local:MyItemsControl> 

作爲說明,爲了繪製以XLoc和YLoc爲中心的橢圓,您應該使用EllipseGeometry替換具有橢圓控件的路徑。

+0

嗯......有一件事:這個ItemsControl綁定到一個集合中有幾種類型的對象,Ellipse就是其中之一。 'GetContainerForItemOverride'似乎並沒有告訴我它需要一個容器的對象。有沒有辦法放置一個'switch'或'if'並每次返回適當的對象? – dotNET

+0

我沒有意識到。如果要使用Path而不是Ellipse,則可以將其Data屬性綁定到視圖模型中的不同幾何圖形。但說實話,對於不同的視圖模型項目有不同的視圖項目正是爲什麼有一個項目容器。所以你應該保持標準的ItemsControl並且通過項類型選擇DataTemplates,或者通過默認的DataTemplates或者ItemTemplateSelector。 – Clemens