2013-01-11 88 views
4

我試圖設置一個WPF DataTemplate將用於LineSystem.Windows.Shapes.Line)對象。WPF DataTemplate失敗的形狀類型

從默認的.NET 4 WPF應用程序,我把我的窗口XAML到:

<Window x:Class="WpfTestDataTemplates.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:system="clr-namespace:System;assembly=mscorlib" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <DataTemplate DataType="{x:Type system:String}" > 
      <TextBlock>It's a string</TextBlock> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type Line}" > 
      <TextBlock>It's a line</TextBlock> 
     </DataTemplate>  
    </Window.Resources> 

    <ListView ItemsSource="{Binding MyItems}" /> 
</Window> 

而後面的代碼是:

using System.Collections.Generic; 
using System.Windows; 
using System.Windows.Shapes; 

namespace WpfTestDataTemplates 
{ 
    public partial class MainWindow : Window 
    { 
     public List<object> MyItems {get; set; } 

     public MainWindow() 
     { 
      InitializeComponent(); 
      DataContext = this; 

      MyItems = new List<object>(); 
      MyItems.Add("The first string"); 
      MyItems.Add(new Line { X1 = 0, Y1 = 0, X2 = 5, Y2 = 5 }); 
      MyItems.Add("The second string"); 
      MyItems.Add(new Rectangle { Height = 5, Width = 15 }); 
      MyItems.Add(42); 
     } 
    } 
} 

產生的窗口如下所示: Resulting window

我期望第二個條目閱讀:它是一條線,但它看起來沒有找到Line類型的DataTemplate。對於沒有顯式DataTemplate的類型,我期望默認渲染是對象的.ToString()成員,但這不是正在發生的事情。所以我期望第四個條目如下:System.Windows.Shapes.Rectangle

爲什麼{x:Type Line}類型不被識別,以及DataTemplate應用於Shape對象的是什麼?

回答

3

A DataTemplate是您用來將UI放置在本身不是UIElements的數據對象上,並且沒有將自己渲染到屏幕上的概念。 LineRectangle但是UIElements - 他們知道如何呈現自己,並且不需要DataTemplate來告訴他們如何。

如果你給你的線條和矩形一些顏色,你會看到他們不顧善意的DataTemplate並在列表作爲一條線,矩形顯示:

MyItems.Add(new Line { X1 = 0, Y1 = 0, X2 = 5, Y2 = 5, 
         Stroke = Brushes.Lime, StrokeThickness = 2 }); 
... 
MyItems.Add(new Rectangle { Height = 5, Width = 15, Fill = Brushes.Blue }); 

ListView objects

要更改UIElements的外觀,通常使用Style(如果它是FrameworkElement)和/或ControlTemplate(如果它是Control)。

編輯:

如果,而不是Line,你有你自己的數據類代表線(姑且稱之爲LineData),你可以使用一個DataTemplate來呈現類,無論如何你」 D類似於:

public class LineData 
{ 
    public LineData(Point start, Point end) 
    { 
     this.Start = start; 
     this.End = end; 
    } 

    public Point Start { get; private set; } 
    public Point End { get; private set; } 

    public double XLength 
    { 
     get { return this.End.X - this.Start.X; } 
    } 
    public double YLength 
    { 
     get { return this.End.Y - this.Start.Y; } 
    } 
} 

... 

MyItems.Add(new LineData(new Point(10, 10), new Point(60, 30))); 

..和所述的DataTemplate ..

<DataTemplate DataType="{x:Type vm:LineData}" > 
    <StackPanel Orientation="Horizontal" SnapsToDevicePixels="True" > 
     <TextBlock>It's a line:</TextBlock> 
     <Grid> 
      <Rectangle Stroke="Black" StrokeThickness="1" 
         Width="{Binding Path=XLength}" Height="{Binding Path=YLength}" /> 
      <Line Stroke="Red" StrokeThickness="2" 
        X1="{Binding Path=Start.X}" Y1="{Binding Path=Start.Y}" 
        X2="{Binding Path=End.X}" Y2="{Binding Path=End.Y}" /> 
     </Grid> 
    </StackPanel> 
</DataTemplate> 

..gives我們:

ListView line

+0

謝謝 - 有點幫助,我要如何使用它的樣式可能是足夠的。所以對於UIElements,WPF甚至不尋找DataTemplate?如果我想將線渲染爲矩形? – Govert

+0

@Govert:您可能無法將'Line'呈現爲'Rectangle',但您可以讓自己的類_representing_一行並在該類上放置一個DataTemplate。我用一個例子更新了我的答案。 – Sphinxxx