2017-09-05 2 views
0

J'ai une structure d'arbre que je l'utilise dans un TreeView comme celui-ciWPF Dessiner la structure d'arbre avec rectanges les uns sur les autres

enter image description here

La racine est dans un objet ObservableCollection<Component>. Un Component a une propriété x, y, width, height, children et name. Je veux utiliser la même arborescence pour dessiner chaque Component avec Rectancle avec des objets enfants dessinés sur le dessus. Quelque chose comme ça

enter image description here

J'ai essayé avec ListBox comme ce

<!-- in Resources --> 
<DataTemplate DataType="{x:Type m:Component}"> 
     <Border BorderBrush="LightBlue" BorderThickness="1"> 
      <Grid Width="{Binding Width}" Height="{Binding Height}"> 
       <Rectangle Cursor="Hand" Fill="AliceBlue"/> 
       <Label Content="{Binding Name}" Margin="5"/> 
      </Grid> 
     </Border> 
    </DataTemplate> 



<ListBox ItemsSource="{Binding ComponentsToDraw}" 
     x:Name="listBox" 
     SelectionMode="Extended" 
     SelectionChanged="listBox_SelectionChanged"> 

    <ListBox.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Canvas Background="Transparent"/> 
     </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 

    <ListBox.ItemContainerStyle> 
     <Style TargetType="ListBoxItem"> 
      <Setter Property="Canvas.Left" Value="{Binding X}"/> 
      <Setter Property="Canvas.Top" Value="{Binding Y}"/> 
     </Style> 
    </ListBox.ItemContainerStyle> 
</ListBox> 

mais ne peut pas obtenir de tirer quoi que ce soit, mais le premier de mon arbre Levet. Également essayé avec un Treeview mais ne peut pas l'obtenir pour arrêter de dessiner mes objets Component comme un panneau de pile.

Espérons que n'importe qui a une solution ou une meilleure manière d'aller.

PS. Je n'ai pas inclus l'élément 'Solution' dans le dessin.

+0

Comment définissez-vous X, Y? global ou relatif? – sTrenat

+0

Un UserControl peut être un meilleur ajustement ici parce que vous obtenez beaucoup plus de contrôle sur elle. Commencez avec un StackPanel de canevas et ajoutez chaque élément imbriqué à son canevas parent. – Lennart

+0

@sTrenat Je pensais à propos si je pouvais obtenir cette structure d'arbre à travailler. Sinon global pourrait fonctionner aussi bien je suppose – smok

Répondre

0

Si vous pouvez accepter la définition de X, Y, dans votre modèle, vous pouvez le faire avec treeView peu Styled:

Voici Xaml:

<TreeView ItemsSource="{Binding ComponentsToDraw}"> 
    <TreeView.Resources> 
     <HierarchicalDataTemplate DataType="{x:Type local:Component}" ItemsSource="{Binding ComponentsToDraw}"> 
      <Grid Canvas.Left="{Binding X}" Canvas.Top="{Binding Y}" Width="{Binding Width}" Height="{Binding Height}" Background="{Binding Color}"> 
       <TextBlock Margin="8,5,0,0" FontWeight="Bold" Text="{Binding Name}" /> 
      </Grid> 
     </HierarchicalDataTemplate> 
     <Style TargetType="{x:Type TreeViewItem}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type TreeViewItem}"> 
         <Canvas> 
          <ContentPresenter x:Name="PART_Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Header"> 
            <ContentPresenter.Style> 
             <Style TargetType="ContentPresenter"> 
              <Setter Property="Canvas.Left" Value="{Binding Path=X}" /> 
              <Setter Property="Canvas.Top" Value="{Binding Path=Y}" /> 
             </Style> 
            </ContentPresenter.Style> 
           </ContentPresenter>  
          <ItemsPresenter/> 
         </Canvas> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </TreeView.Resources>   
</TreeView> 

Vous avez ici le style de ItemTemplate, à makde ContentPresenter en tant que Canvas, et HierarichalDataTemplate, pour que votre DataTemplate ressemble à Rectangle avec du texte.

Voici le modèle i utilisé:

public class Component 
{ 
    public Component() { } 
    public ObservableCollection<Component> ComponentsToDraw { set; get; } = new ObservableCollection<Component>(); 
    public double X { set; get; } 
    public double Y { set; get; } 
    public double Width { set; get; } 
    public double Height { set; get; } 
    public Brush Color { set; get; } 
    public string Name { set; get; } 
} 

Et, en ViewModel aussi fait vos commandes, you'r écrit quelque chose comme:

var Solution = new Component() { X = 0, Y = 0, Height = 300, Width = 500, Name = "Solution", Color = new SolidColorBrush(Colors.White)}; 
var PC = new Component() { X = 0, Y = 0, Height = 300, Width = 245, Name = "PC", Color = new SolidColorBrush(Colors.LightBlue) }; 
var PC2 = new Component() { X = 255, Y = 0, Height = 195, Width = 245, Name = "PC2", Color = new SolidColorBrush(Colors.LightBlue) }; 
var SubDrawingComponent = new Component() { X = 50, Y = 50, Height = 200, Width = 150, Name = "Drawing Component", Color = new SolidColorBrush(Colors.GreenYellow) }; 
var DrawingComponent = new Component() { X = 255, Y = 205, Height = 42.5, Width = 245, Name = "Drawing Component", Color = new SolidColorBrush(Colors.GreenYellow) }; 
var DrawingComponent2 = new Component() { X = 255, Y = 257.5, Height = 42.5, Width = 200, Name = "Drawing Component2", Color = new SolidColorBrush(Colors.GreenYellow) }; 
Solution.ComponentsToDraw.Add(PC); 
Solution.ComponentsToDraw.Add(PC2); 
Solution.ComponentsToDraw.Add(DrawingComponent); 
Solution.ComponentsToDraw.Add(DrawingComponent2); 
PC.ComponentsToDraw.Add(SubDrawingComponent); 
ComponentsToDraw.Add(Solution); 

Pour chaque élément Drawing Component, vous déclarant X et Y, qui sont Relatives à son parent. Voici à quoi il ressemble:

enter image description here

Je sais, je l'ai écrit quelques champs avec PascalCase, désolé: D

+0

Je vais essayer votre solution dès que j'ai le temps :) – smok

+0

Il est presque parfait. Mais pour une raison quelconque, je ne peux pas obtenir l'index z pour fonctionner. Les sous-composants sont cachés derrière leur parent – smok

+0

Etes-vous sûr de le configurer correctement? Je veux dire, pour les enfants, parent ZIndex + = 1? – sTrenat