统一网格行和列

时间:2010-06-02 20:10:36

标签: wpf

我正在尝试根据UniformGrid创建一个网格来显示每个单元格的坐标,我想在X和Y轴上显示这样的值,如下所示:

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

无论如何,为了做到这一点,我需要知道Uniform网格中的列数和行数,并且我尝试覆盖排列/绘图发生的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 个答案:

答案 0 :(得分: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));

我实际上并没有运行代码,所以可能存在一些拼写错误。

答案 1 :(得分: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

谢谢!