0

I was trying out to create a Custom Grid where it re sizes and relocates it's children dynamically, based on the largest available child dimension and window dimension. This means I will have to redraw my rows and columns definitions on the fly. The below given is my Custom Grid Code

public class GridPanel : Grid
{
    #region Fields

    Size maxItemSize;
    int maxPossibleColumns = 0;
    int maxPossibleRows = 0;

    #endregion

    #region Overrides

    protected override Size MeasureOverride(Size constraint)
    {
        this.ShowGridLines = true;
        GetMaxItemSize(constraint);
        //SetupGridCells(constraint);
        return constraint;
    }

    protected override Size ArrangeOverride(Size arrangeSize)
    {
        //SetupGridCells(arrangeSize); 
        return base.ArrangeOverride(arrangeSize); //Caught a nullReferrence exception
    }



    #endregion

    #region Methods

    private void GetMaxItemSize(Size availableSize)
    {
        foreach (UIElement item in Children)
        {
            item.Measure(availableSize);
            maxItemSize = item.DesiredSize.Width > maxItemSize.Width ? item.DesiredSize : maxItemSize;
        }
    }

    private void SetupGridCells(Size finalSize)
    {
        ColumnDefinition spaceWidth;
        ColumnDefinition cellWidth;

        RowDefinition spaceHeight;
        RowDefinition cellHeight;

        maxPossibleColumns = (int)(finalSize.Width / maxItemSize.Width);
        for (int i = 0; i < maxPossibleColumns; i++)
        {
            spaceWidth = new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) };
            cellWidth = new ColumnDefinition { Width = new GridLength(maxItemSize.Width) };

            this.ColumnDefinitions.Add(spaceWidth);//***
            this.ColumnDefinitions.Add(cellWidth);//***
        }
        spaceWidth = new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) };
        this.ColumnDefinitions.Add(spaceWidth);//***

        /////////////////////////////////////////////////////////////////////////////////////////////

        maxPossibleRows = (int)(finalSize.Height / maxItemSize.Height);
        for (int i = 0; i < maxPossibleRows; i++)
        {
            spaceHeight = new RowDefinition { Height = new GridLength(1, GridUnitType.Star) };
            cellHeight = new RowDefinition { Height = new GridLength(1, GridUnitType.Star) };

            this.RowDefinitions.Add(spaceHeight);//***
            this.RowDefinitions.Add(cellHeight);//***
        }
        spaceHeight = new RowDefinition { Height = new GridLength(1, GridUnitType.Star) };
        this.RowDefinitions.Add(spaceHeight);
    }

    #endregion
}

and this is how I'd use the panel

<Panels:GridPanel>
        <Rectangle Height="10" Width="10" Fill="Red" />
        <Rectangle Height="20" Width="20" Fill="Black" />
        <Rectangle Height="30" Width="30" Fill="Green" />
        <Rectangle Height="40" Width="40" Fill="Blue" />
        <Rectangle Height="50" Width="50" Fill="Aqua" />
        <Rectangle Height="60" Width="60" Fill="Wheat" />
        <Rectangle Height="70" Width="70" Fill="Blue" />
        <Rectangle Height="80" Width="80" Fill="DarkBlue" />
        <Rectangle Height="90" Width="90" Fill="DarkGoldenrod" />
        <Rectangle Height="100" Width="100" Fill="Gainsboro" />
        <Rectangle Height="110" Width="110" Fill="Pink" />
        <Rectangle Height="120" Width="120" Fill="Brown" />
    </Panels:GridPanel>

SetupGridCells() is the method inside which I'm trying to redraw Rows and columns. The issue is that even if I call this method inside ArrangeOveride() or MeasureOverride(), it throws a nullReference exception in return base.ArrangeOverride(arrangeSize); On further debugging I noticed that this.ColumnDefinitions.Add(spaceWidth);//* (those lines marked with the comment //*) is causing the issue.

Could some one point out what the issue would be? Thanks in advance

  • Why derive from Grid? Users of your GridPanel are not supposed to set any Grid.Row or Grid.Column values. Derive directly from Panel, implement MeasureOverride and ArrangeOverride, and you're done. – Clemens Mar 26 '15 at 11:58
  • If _after_ debugging per the advice in the duplicate question, you are still having problems, please ask a new question that is more specific than simply stating "it throws a `NullReferenceException`", in which you: describe clearly and completely what you've done to debug the problem; provide the full stack trace for the exception; and include [a good, _minimal_, _complete_ code example](http://stackoverflow.com/help/mcve) that reliably reproduces the problem. – Peter Duniho Jun 08 '15 at 20:26
  • Every time the user changes the size of the page or screen, your MeasureOverride method would add more row definitions and column definitions to the grid. MeasureOverride can be called more than once and your code should behave appropriately in that situation. – David Rector Aug 13 '15 at 19:34
  • Nowhere are the children assigned a specific row or column. they are all in row 0, column 0. As was said, derive from panel and add your own code to measure and position the child elements. It's easier than trying to dynamically add rows and columns to an underlying grid. – David Rector Aug 13 '15 at 19:36
  • And finally, it may be the simple case that RowDefinitions is null. try adding an empty element to your XAML grid and see if that helps... and do the same for columns. or maybe just look in the debugger and see if RowDefinitons or ColumnDefinitions is not null. The derive from a Panel insetad of a grid and do the positioning yourself! – David Rector Aug 13 '15 at 19:39

0 Answers0