2009-08-03 7 views
1

Je ne peux pas envelopper la tête autour de la façon d'accomplir le rendu cetteWPF Affichage parent relation enfant

public class Shape{} 
public class Circle: Shape{} 
public class Square: Shape 
{ 
    public List<Circle> CircleList{ get; private set; } 
} 

J'ai une liste qui contient des objets de forme, maintenant ce que je veux accomplir est d'avoir chaque objet rendu dans un la grille.

Si l'objet est un carré il devrait y avoir une grille imbriquée qui contient des éléments Cercle de la propriété CircleList

J'ai essayé avec un ItemsControl et un HierarchicalDataTemplate, n'a pas pu le faire fonctionner, j'ai essayé d'imbrication un ItemsControl à l'intérieur d'un ItemsControl, je suis assez nouveau à WPF donc je suis en train de tâtonner ici en ne sachant pas quelle serait la "bonne" solution. J'ai réussi à rendre le dessus dans un TreeView, mais ce que j'essaye d'accomplir est un tableau qui rend des formes.

MISE À JOUR

Le « DrawingBoard » doit contenir des éléments, chaque élément doit être rendu dans un récipient.

Si l'objet est de type Carré, le conteneur Carré doit avoir un conteneur imbriqué pour contenir les objets Circle de la propriété CircleList.

+0

Peut-être que je suis juste un peu confus par une faute de frappe. Il est évident que Square dérive de Shape, mais vous avez {} des parenthèses après ça ... ne devraient-ils pas être là? –

+0

Juste des parenthèses vides pour la classe où le constructeur et tel devrait être – thmsn

+0

Mais ne sont pas les 3 lignes après que la définition de la classe? –

Répondre

1

Scott est assez proche mais pas tout à fait là; la définition du DataContext de la grille ne rendra pas les objets Circle contenus. Ce dont vous avez besoin est un contrôle incorporé qui peut afficher ses propres éléments, puis lier la propriété ItemsSource de ce contrôle à CircleList.

J'ai construit un exemple en utilisant vos classes originales qui le démontrent. Voici le code-behind:

public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent(); 

     Square square = new Square(); 
     square.CircleList = new List<Circle>() { new Circle(25) }; 
     _shapes.Add(square); 
    } 

    private List<Shape> _shapes = new List<Shape>(); 

    public List<Shape> Shapes 
    { 
     get { return _shapes; } 
    } 
} 

public abstract class Shape { } 

public class Circle : Shape 
{ 
    public double Diameter { get; private set; } 

    public Circle(double diameter) 
    { 
     Diameter = diameter; 
    } 
} 

public class Square : Shape 
{ 
    public List<Circle> CircleList { get; set; } 
} 

Ainsi, vous pouvez voir que j'ai ajouté une seule place à ma liste de formes, qui contient un cercle de diamètre 25. Notez que cela n'ajoute pas de support pour le positionnement des formes à l'aide coordonnées absolues; Je suppose que vous avez déjà quelque chose en place pour cela.

Maintenant, le XAML:

<Window x:Class="TestWpfApplication.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="clr-namespace:TestWpfApplication" 
Title="Window1" 
DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
<Window.Resources> 
    <DataTemplate DataType="{x:Type local:Circle}"> 
     <Ellipse Stroke="Black" 
       Width="{Binding Diameter}" 
       Height="{Binding Diameter}"/> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type local:Square}"> 
     <Border BorderThickness="1" BorderBrush="Black"> 
      <ItemsControl ItemsSource="{Binding CircleList}"/> 
     </Border> 
    </DataTemplate> 
</Window.Resources> 

<ListBox ItemsSource="{Binding Shapes}"> 
    <ListBox.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Canvas/> 
     </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 
</ListBox> 

Voici vos DataTemplates; vous pouvez voir le cercle est rendu simplement avec une ellipse. The Square, d'autre part, a un ItemsControl intégré qui rend ses éléments contenus. J'ai également dessiné une bordure autour d'elle pour faire la forme carrée.

Voici le résultat:

alt text http://img212.imageshack.us/img212/8658/squarewithcirclecontent.png

+0

+1 - J'ai été un peu confus par la question initiale en disant qu'il les affichait dans une grille, et je me suis dit qu'il avait un autre modèle de données pour rendre une "grille" à partir d'une liste. Vous avez résolu cela avec un ItemsControl. –

+0

gentil, au moins je l'ai eu à rendre maintenant: D maintenant j'ai quelque chose à travailler avec :) – thmsn

0

Vous pouvez essayer d'utiliser deux DataTemplates, un pour un cercle (juste pour un cercle) et un pour un carré. Le DataTemplate carré doit restituer une grille (juste lui donner une bordure pour la faire ressembler à un carré) et ensuite définir le DataContext de la Grille imbriquée = "{Binding CircleList}". Je ne suis pas sûr à 100% de la façon dont vous convertissez une liste de formes en une grille, mais ça sonne comme si vous l'aviez déjà résolu, donc je vais simplement l'omettre pour plus de simplicité. :)

+0

Je suis un peu confus quant à ce que je serais en définissant les données spécifiques, fondamentalement si je savais comment le faire , je voudrais utiliser un ItemsControl, je veux avoir un "tableau" ce tableau contient une liste d'éléments, ces éléments doivent être rendus d'une certaine manière. – thmsn

+0

@thmsn - Le "tableau" que vous décrivez est un peu étrange, du point de vue de la fonctionnalité. Cela ne permettra pas aux éléments de se chevaucher. Pourquoi ne pas simplement utiliser un objet de toile, jeter toutes vos formes là-dedans, et laissez-les les rendre. Alors vous n'avez pas à vous soucier de ce qui est "à l'intérieur" de quoi. –

+0

la raison pour laquelle je veux qu'il soit imbriqué est que la position des objets enfants doit être relative à la position des parents :) ils devraient permettre de se chevaucher, donc une toile serait probablement la bonne chose, ils ont toujours besoin d'une toile nsted – thmsn

Questions connexes