2010-06-02 7 views
1

Je suis en train de faire une grille basée sur un UniformGrid pour montrer les coordonnées de chaque cellule, et je veux montrer les valeurs sur les axes X et Y comme ceci:grille uniforme lignes et des colonnes

_A_ _B_ _C_ _D_ 
1 |___|___|___|___| 
2 |___|___|___|___| 
3 |___|___|___|___| 
4 |___|___|___|___| 

Quoi qu'il en soit, pour cela, j'ai besoin de connaître le nombre de colonnes et de lignes dans la grille Uniforme, et j'ai essayé de contourner les 3 méthodes les plus basiques, mais les colonnes et les lignes sont 0, même bien que j'ai quelques contrôles dans ma grille. Quelle méthode puis-je remplacer afin que ma grille cartésienne sache combien de colonnes et de lignes elle a?

C#:

public class CartesianGrid : UniformGrid 
{ 
    protected override Size MeasureOverride(Size constraint) 
    { 
     Size size = base.MeasureOverride(constraint); 

     int computedColumns = this.Columns; // always 0 
     int computedRows = this.Rows; // always 0 

     return size; 
    } 

    protected override Size ArrangeOverride(Size arrangeSize) 
    { 
     Size size = base.ArrangeOverride(arrangeSize); 

     int computedColumns = this.Columns; // always 0 
     int computedRows = this.Rows; // always 0 

     return size; 
    } 

    protected override void OnRender(DrawingContext dc) 
    {`enter code here` 
     int computedColumns = this.Columns; // always 0 
     int computedRows = this.Rows; // always 0 

     base.OnRender(dc); 
    } 
} 

XAML:

<local:CartesianGrid> 
    <Label Content="Hello" /> 
    <Label Content="Hello" /> 
    <Label Content="Hello" /> 
    <Label Content="Hello" /> 
    <Label Content="Hello" /> 
    <Label Content="Hello" /> 
</local:CartesianGrid> 

Toute aide est grandement appréciée. Merci!

Répondre

2

Aucune propriété exposée ne vous donne cette information. Si vous avez un réflecteur, vous pouvez voir le calcul qu'ils font dans la méthode UpdateComputedValues pour trouver le nombre de lignes et de colonnes qu'ils utilisent.

Dans le cas où Rows, Columns et FirstColumn sont nuls, vous pouvez utiliser quelque chose comme ça

int numVisibleChildren = this.Children.Count((c) => c.Visibility != Visibility.Collapsed); 
int numColumns = (int)Math.Ceiling(Math.Sqrt(numVisibleChildren)); 
int numRows = (int)Math.Floor(Math.Sqrt(numVisibleChildren)); 

Je ne l'ai pas fait exécuter le code si donc il y a probablement des fautes de frappe.

+0

Wow votre solution est vraiment simple, seulement j'ai dû changer numRows pour utiliser Math.Ceiling aussi. Je suis venu avec une autre solution moi-même, mais j'aime beaucoup plus le tien (posté ma solution dans la question). Merci! – Carlo

+0

Désolé, mais votre solution n'a pas fonctionné, bien que ce soit beaucoup plus simple. Dans notre cas, le nombre de colonnes et le nombre de lignes ne sont pas les mêmes. J'ai donc dû utiliser ma solution pour calculer le nombre réel de colonnes et de lignes, sans supposer que ces nombres sont les mêmes. Merci! – Carlo

+0

En fait nvm, c'était plus facile depuis le début, dans notre projet les colonnes et les lignes sont définies spécifiquement par DependencyProperty, votre solution devrait fonctionner correctement lorsque les colonnes et les lignes ne sont pas définies, ce que je visais en premier. Merci! – Carlo

1

est ici la solution complète, poignées spécifiant ou non spécifier les colonnes et les lignes du UniformGrid:

public class CartesianGrid : UniformGrid 
{ 
    private int _columns; 
    private int _rows; 
    private int _margin = 20; 

    public CartesianGrid() 
    { 
     // add some margin so the letters and numbers do show up 
     this.Margin = new Thickness(_margin, _margin, 0, 0); 
    } 

    protected override void OnRender(DrawingContext dc) 
    { 
     double xOffset = (this.RenderSize.Width/_columns); 
     double yOffset = (this.RenderSize.Height/_rows); 

     double xCenterOffset = xOffset/2; 
     double yCenterOffset = yOffset/2.3; 

     for (int i = 0; i < _columns; i++) 
     { 
      dc.DrawText(
       new FormattedText((i + 1).ToString(), 
       CultureInfo.CurrentCulture, 
       FlowDirection.LeftToRight, 
       new Typeface("Arial"), 
       20, 
       Brushes.Black), new Point((i * xOffset) + xCenterOffset, _margin * -1)); 
     } 

     for (int i = 0; i < _rows; i++) 
     { 
      dc.DrawText(
       new FormattedText(((char)(i + 65)).ToString(), 
       CultureInfo.CurrentCulture, 
       FlowDirection.LeftToRight, 
       new Typeface("Arial"), 
       20, 
       Brushes.Black), new Point(_margin * -1, (i * yOffset) + yCenterOffset)); 
     } 

     base.OnRender(dc); 
    } 

    protected override Size ArrangeOverride(Size arrangeSize) 
    { 
     if (this.Columns != 0 && this.Rows != 0) 
     { 
      _rows = this.Rows; 
      _columns = this.Columns; 

      return base.ArrangeOverride(arrangeSize); 
     } 
     else 
     { 
      Size arrangedSize = base.ArrangeOverride(arrangeSize); 

      double maxChildDesiredWidth = 0.0; 

      double maxChildDesiredHeight = 0.0; 

      // Measure each child, keeping track of max desired width & height. 
      for (int i = 0, count = Children.Count; i < count; ++i) 
      { 
       UIElement child = Children[i]; 

       Size childDesiredSize = child.DesiredSize; 

       if (maxChildDesiredWidth < childDesiredSize.Width) 
       { 
        maxChildDesiredWidth = childDesiredSize.Width; 
       } 
       if (maxChildDesiredHeight < childDesiredSize.Height) 
       { 
        maxChildDesiredHeight = childDesiredSize.Height; 
       } 
      } 

      if (maxChildDesiredHeight == 0 || maxChildDesiredWidth == 0) 
       return arrangedSize; 

      _columns = Convert.ToInt32(Math.Floor(this.DesiredSize.Width/maxChildDesiredWidth)); 
      _rows = Convert.ToInt32(Math.Floor(this.DesiredSize.Height/maxChildDesiredHeight)); 

      return arrangedSize; 
     } 
    } 
} 

BTW, ce que je voulais réaliser:

http://wpfdude.blogspot.com/2010/06/cartesian-grid.html

Merci!

Questions connexes