2016-12-25 5 views
-2

Depuis quelques jours, j'ai essayé d'envelopper ma tête autour de la mise en page suivante de TextBlocks:WPF - Complexe TextBlock mise en page

-------------------- ----------- 
|   1  | |   | 
-------------------- | 3 | 
|  2  | |   | 
----------------- ----------- 

Toutes les TextBlocks ont une largeur dynamique. Ils ont une hauteur fixe et sont dans un conteneur de taille fixe. Ils doivent répondre aux exigences suivantes:

  • 2 a la priorité maximale - il doit toujours être à pleine longueur.
  • 3 peut remplir l'espace restant à gauche après le calibrage 2.

Quand ignorant TextBlock 1, ces deux exigences pourrait être remplie en mettant les deux autres TextBlocks dans une grille, avec des colonnes réglées sur « auto » et " *" respectivement.

Il y a une troisième condition cependant:

  • 1 prend tout l'espace qu'il peut, mais sans restreindre 3.

Exemples:

contenu à long dans le bloc 3 (bloc 2 le contenu est entier, le contenu du bloc 3 est découpé):

----------------- ------------- 
|  1  | |   | 
----------------- |  3  | 
|  2  | |   | 
----------------- ------------- 

Contenu court dans le bloc 3 (les blocs 2 et 3 ont une longueur totale; le bloc 1 remplit l'espace restant):

--------------------- --------- 
|   1   | |  | 
--------------------- | 3 | 
|  2  |  |  | 
-----------------  --------- 

Existe-t-il un moyen d'obtenir cette disposition dans WPF? Comment?

Répondre

0

Je ne pense pas que ce soit possible avec du XAML pur. Une façon d'accomplir vos exigences est de mettre en place votre propre panel qui fait tout le possible. Voici une mise en œuvre:

public class SpecialPanel : Panel 
{ 
    protected override Size MeasureOverride (Size constraint) 
    { 
     foreach (UIElement child in Children) 
     { 
      child.Measure (constraint); 
     } 

     return constraint; 
    } 

    protected override Size ArrangeOverride (Size arrangeSize) 
    { 
     if (VisualChildrenCount != 3) 
     { 
      return (arrangeSize); 
     } 

     Size sizeLabel0 = InternalChildren[0].DesiredSize; 
     Size sizeLabel1 = InternalChildren[1].DesiredSize; 
     Size sizeLabel2 = InternalChildren[2].DesiredSize; 

     InternalChildren[1].Arrange (new Rect (0, sizeLabel0.Height, sizeLabel1.Width, sizeLabel1.Height)); 
     var maxRemainingWidthFor2 = arrangeSize.Width - sizeLabel1.Width; 

     if (maxRemainingWidthFor2 <= 0) 
     { 
      InternalChildren[0].Arrange (new Rect (0, 0, sizeLabel0.Width, sizeLabel0.Height)); 
     } 
     else 
     { 
      if (maxRemainingWidthFor2 < sizeLabel2.Width) 
      { 
       InternalChildren[2].Arrange (new Rect (arrangeSize.Width - maxRemainingWidthFor2, 0, maxRemainingWidthFor2, sizeLabel2.Height)); 
       InternalChildren[0].Arrange (new Rect (0, 0, Math.Min (sizeLabel0.Width, sizeLabel1.Width), sizeLabel0.Height)); 
      } 
      else 
      { 
       var max0 = arrangeSize.Width - maxRemainingWidthFor2; 
       var width0 = Math.Min (sizeLabel0.Width, max0); 

       InternalChildren[2].Arrange (new Rect (arrangeSize.Width - sizeLabel2.Width, 0, sizeLabel2.Width, sizeLabel2.Height)); 
       InternalChildren[0].Arrange (new Rect (0, 0, arrangeSize.Width - sizeLabel2.Width, sizeLabel0.Height));. 
      } 
     } 

     return arrangeSize; 
    } 
} 

Utilisation:

<local:SpecialPanel> 
     <Label 
      x:Name="Label1" 
      VerticalContentAlignment="Center" 
      Content="TextBlock00000000000000" /> 
     <Label 
      x:Name="Label2" 
      VerticalContentAlignment="Center" 
      Content="TextBloc111111111111" /> 
     <Label 
      x:Name="Label3" 
      HorizontalContentAlignment="Center" 
      VerticalContentAlignment="Center" 
      Content="Label333333" /> 
    </local:SpecialPanel> 
+0

Merci pour la réponse. Cependant, cela ne fonctionne pas comme prévu pour le second exemple. J'ai modifié votre code pour le faire fonctionner, la dernière branche 'else' doit être changée en ceci:' InternalChildren [2] .Arrange (nouveau Rect (arrangementSize.Width - tailleLabel2.Width, 0, tailleLabel2.Width, tailleLabel2. La taille)); InternalChildren [0] .Arrange (nouveau Rect (0, 0, arrangeSize.Width - tailleLabel2.Width, tailleLabel0.Height)); '. Si vous modifiez votre réponse, je l'accepterai. – Mastah

+0

Je suis heureux que vous ayez eu l'idée et soyez capable d'adapter la logique à vos besoins. J'ai mis à jour ma réponse. – gomi42