代码之家  ›  专栏  ›  技术社区  ›  Carlo

均匀网格行和列

wpf
  •  1
  • Carlo  · 技术社区  · 14 年前

    我正试图基于一个统一网格创建一个网格来显示每个单元格的坐标,我想在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 回复  |  直到 14 年前
        1
  •  2
  •   Bryan Anderson    14 年前

    没有任何财产暴露给你这些信息。如果你有反射镜,你可以看到他们在 UpdateComputedValues 方法来查找它们使用的行数和列数。

    在这种情况下 Rows , Columns FirstColumn 是零,你可以用这样的东西

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

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

        2
  •  1
  •   Carlo    14 年前

    以下是完整的解决方案,即指定或不指定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

    谢谢!