Wpf 统一网格行和列

Wpf 统一网格行和列,wpf,Wpf,我试图基于UniformGrid创建一个网格来显示每个单元格的坐标,我想显示X轴和Y轴上的值,如下所示: _A_ _B_ _C_ _D_ 1 |___|___|___|___| 2 |___|___|___|___| 3 |___|___|___|___| 4 |___|___|___|___| 无论如何,为了做到这一点,我需要知道统一网格中的列数和行数,并且我尝试覆盖3种最基本的方法,其中排列/绘制发生,但其中的列数和行数为0,即使我的网格中有一些控件。我可以重写什么方法使笛卡尔网格知

我试图基于UniformGrid创建一个网格来显示每个单元格的坐标,我想显示X轴和Y轴上的值,如下所示:

   _A_ _B_ _C_ _D_
1 |___|___|___|___|
2 |___|___|___|___|
3 |___|___|___|___|
4 |___|___|___|___|
无论如何,为了做到这一点,我需要知道统一网格中的列数和行数,并且我尝试覆盖3种最基本的方法,其中排列/绘制发生,但其中的列数和行数为0,即使我的网格中有一些控件。我可以重写什么方法使笛卡尔网格知道它有多少列和行

C#:

XAML:



非常感谢您的帮助。谢谢

没有公开的属性提供这些信息。如果您有reflector,您可以在
updateComputerdValues
方法中查看它们所做的计算,以找到它们使用的行数和列数

如果
第一列
为零,则可以使用类似的方法

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

我还没有实际运行代码,因此可能有一些输入错误。

以下是完整的解决方案,用于指定或不指定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;
        }
    }
}
公共类CartesianGrid:UniformGrid
{
专用int_列;
私有整数行;
私人内部利润率=20;
公共CartesianGrid()
{
//添加一些边距,使字母和数字显示出来
此.Margin=新厚度(_-Margin,_-Margin,0,0);
}
受保护的覆盖无效OnRender(DrawingContext dc)
{
double xOffset=(this.RenderSize.Width/_列);
double yOffset=(this.RenderSize.Height/_行);
双xCenterOffset=xOffset/2;
双Y中心偏移=Y偏移/2.3;
对于(int i=0;i<\u列;i++)
{
dc.DrawText(
新的格式化文本((i+1).ToString(),
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
新字体(“Arial”),
20,
黑色),新点((i*xOffset)+xCenterOffset,_margin*-1));
}
对于(int i=0;i<\u行;i++)
{
dc.DrawText(
新的格式化文本(((char)(i+65)).ToString(),
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
新字体(“Arial”),
20,
画笔。黑色),新点(_margin*-1,(i*yOffset)+yCenterOffset));
}
base.OnRender(dc);
}
受保护的替代尺寸ArrangeOverride(尺寸arrangeSize)
{
if(this.Columns!=0&&this.Rows!=0)
{
_rows=this.rows;
_columns=this.columns;
返回base.ArrangeOverride(arrangeSize);
}
其他的
{
大小arrangedSize=base.ArrangeOverride(arrangeSize);
双maxChildDesiredWidth=0.0;
双maxChildDesiredHeight=0.0;
//测量每个孩子,跟踪所需的最大宽度和高度。
for(int i=0,count=Children.count;i
顺便说一句,这就是我想要实现的目标:


谢谢

哇,你的解决方案真的很简单,只是我不得不改变numRows来使用数学。天花板也一样。我自己提出了另一个解决方案,但我更喜欢你的(在问题中发布了我的解决方案)。谢谢很抱歉,您的解决方案不起作用,尽管要简单得多。在我们的例子中,列数和行数是不同的。因此,我必须使用我的解决方案来计算列和行的实际数量,而不假设这些数字是相同的。谢谢实际上nvm,从一开始就比较容易,在我们的项目中,列和行是通过DependencyProperty专门设置的,当列和行没有设置时,您的解决方案应该可以很好地工作,这正是我最初的目标。谢谢
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));
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;
        }
    }
}