2010-06-02 65 views
1

我试图让根据UniformGrid一个表格显示每个单元的坐标,我想表明的X值和Y轴,像这样:均匀网格的行和列

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

无论如何,为了做到这一点,我需要知道统一网格中的列和行的数量,我尝试覆盖排列/绘图发生的3种最基本的方法,但其中的列和行是0,甚至是尽管我在网格中有一些控件。我可以重写什么方法,以便我的笛卡尔网格知道它有多少个列和行?

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> 

任何帮助是极大的赞赏。谢谢!

回答

2

没有财产暴露给你的信息。如果有反射器,您可以在UpdateComputedValues方法中看到他们的计算,以查找它们使用的行数和列数。

的情况下RowsColumnsFirstColumn是零,您可以使用这样的事情

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)); 

我没有真正运行的代码,但这样也有可能是一些错别字。

+0

哇你的解决方案非常简单,只有我不得不改变numRows来使用Math.Ceiling。我自己想出了另一种解决方案,但我更喜欢你的(在问题中发布了我的解决方案)。谢谢! – Carlo 2010-06-02 22:19:01

+0

对不起,但你的解决方案没有效果,虽然简单得多。在我们的例子中,列数和行数是不一样的。所以我不得不使用我的解决方案来计算实际的列数和行数,而不是假设这些数字是相同的。谢谢! – Carlo 2010-06-02 23:17:52

+0

事实上,nvm从一开始就比较容易,在我们的项目中,列和行是通过DependencyProperty特别设置的,当列和行未设置时,您的解决方案应该可以正常工作,这正是我一开始就瞄准的目标。谢谢! – Carlo 2010-06-02 23:21:38

1

下面是完整的解决方案,处理指定或不指定的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; 
     } 
    } 
} 

顺便说一句,这就是我想实现:

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

谢谢!