src/Misc/EFTools/DesignXmlCore/VirtualTreeGrid/Provider/VirtualTree.cs
/// <summary>
///     For the given row and column, retrieve the range of cells that form the
///     blank region for the given items. The anchor cell, which is the only
///     cell in the range that is not a blank item, will always be the top left
///     cell. In most cases, the returned range will simply be the input cell.
/// </summary>
/// <param name="row">The row coordinate</param>
/// <param name="column">The column coordinate</param>
/// <param name="columnPermutation">
///     The column permutation to apply. If this
///     is provided, then column is relative to the column permutation, not
///     the unpermuted position.
/// </param>
/// <returns>The expansion for this row and column</returns>
For the given row and column, retrieve the range of cells that form the
blank region for the given items. The anchor cell, which is the only
cell in the range that is not a blank item, will always be the top left
cell. In most cases, the returned range will simply be the input cell.
For the given row and column retrieve the range of cells that form the blank region for the given items . The anchor cell which is the only cell in the range that is not a blank item will always be the top left cell . In most cases the returned range will simply be the input cell .
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
        protected BlankExpansionData GetBlankExpansion(int row, int column, ColumnPermutation columnPermutation)
        {
            if (!MultiColumnSupport)
            {
                return new BlankExpansionData(row, column);
            }
            else if (columnPermutation != null)
            {
                var permutedColumns = columnPermutation.GetColumnExpansion(column, ColumnWidthOfRow(row) - 1);
                var nativeData = GetBlankExpansion(
                    row,
                    (permutedColumns.AnchorColumn == VirtualTreeConstant.NullIndex)
                        ? 0
                        : columnPermutation.GetNativeColumn(permutedColumns.AnchorColumn), null);
                return new BlankExpansionData(
                    nativeData.TopRow, permutedColumns.LeftColumn, nativeData.BottomRow, permutedColumns.RightColumn,
                    permutedColumns.AnchorColumn);
            }
            else
            {
                int topRow;
                int leftColumn;
                int bottomRow;
                int rightColumn;
                topRow = bottomRow = row;
                leftColumn = rightColumn = column;
                var localColumn = column;
                var lastSubItem = false;
                var pos = TrackCell(row, ref localColumn, ref lastSubItem);
                var lastNonBlankColumn = pos.ParentNode.GetColumnCount(pos.Index) - 1;
                var columnDiff = lastNonBlankColumn - localColumn;
                var localColumnAdjusted = false;
                var rowPadding = 0;
                if (columnDiff <= 0)
                {
                    var tn = pos.ParentNode;
                    var nextIndex = pos.Index;
                    var onLastItem = tn.InSubItemColumn;
                    while (tn != null)
                    {
                        if (onLastItem)
                        {
                            if (nextIndex < (tn.FullCount - 1))
                            {
                                onLastItem = false;
                            }
                            else
                            {
                                nextIndex = tn.Index;
                            }
                        }
                        if (tn.SubItemRoot)
                        {
                            if (tn.MultiColumn)
                            {
                                tn = null;
                            }
                            else
                            {
                                var subitemOwner = tn.Parent;
                                if (onLastItem)
                                {
                                    rowPadding = subitemOwner.ImmedSubItemGain - tn.FullCount;
                                    if (tn.ComplexSubItem)
                                    {
                                        ++rowPadding;
                                    }
                                }
                                lastNonBlankColumn = subitemOwner.Parent.GetColumnCount(subitemOwner.Index) - 1;
                                columnDiff = lastNonBlankColumn - subitemOwner.FirstSubItem.ColumnOfRootNode(tn);
                                if (columnDiff <= 0)
                                {
                                    tn = null;
                                }
                            }
                            break;
                        }
                        tn = tn.Parent;
                    }
                    if (tn == null)
                    {
                        if (!pos.ParentNode.InSubItemColumn)
                        {
                            localColumn += columnDiff;
                            localColumnAdjusted = true;
                        }
                        leftColumn += columnDiff;
                        rightColumn = ColumnCount - 1;
                    }
                }
                var tnChild = pos.ParentNode.GetChildNode(pos.Index);
                if (localColumn > 0
                    && tnChild != null)
                {
                    var sn = tnChild.SubItemAtColumn(localColumn);
                    var tnSubItemRoot = (sn == null) ? null : sn.RootNode;
                    Debug.Assert(tnChild == null || !tnChild.ComplexSubItem); 
                    if (tnSubItemRoot != null
                        && tnSubItemRoot.Expanded
                        && tnSubItemRoot.FullCount > 0)
                    {
                        if (localColumnAdjusted)
                        {
                            var lastRowInCell = tnSubItemRoot.FullCount;
                            if (tnSubItemRoot.ComplexSubItem)
                            {
                                --lastRowInCell;
                            }
                            if (pos.SubItemOffset >= lastRowInCell)
                            {
                                topRow -= pos.SubItemOffset;
                                bottomRow = topRow + tnChild.ImmedSubItemGain;
                                topRow += lastRowInCell;
                            }
                            tnChild = null;
                        }
                        else
                        {
                            if (pos.SubItemOffset > 0)
                            {
                                topRow -= pos.SubItemOffset;
                                bottomRow = topRow + tnChild.ImmedSubItemGain;
                                topRow += tnSubItemRoot.FullCount;
                                if (tnSubItemRoot.ComplexSubItem)
                                {
                                    --topRow;
                                }
                                tnChild = null;
                            }
                        }
                    }
                }
                if (tnChild != null)
                {
                    if (pos.SubItemOffset > 0)
                    {
                        topRow -= pos.SubItemOffset;
                        bottomRow = topRow + tnChild.ImmedSubItemGain;
                    }
                    else
                    {
                        bottomRow += tnChild.ImmedSubItemGain;
                    }
                }
                if (rowPadding != 0)
                {
                    bottomRow += rowPadding;
                }
                return new BlankExpansionData(topRow, leftColumn, bottomRow, rightColumn, leftColumn);
            }
        }
[ SuppressMessage ( " " , " " ) ] protected BlankExpansionData GetBlankExpansion ( int row , int column , ColumnPermutation columnPermutation ) { if ( ! MultiColumnSupport ) { return new BlankExpansionData ( row , column ) ; } else if ( columnPermutation != null ) { var permutedColumns = columnPermutation . GetColumnExpansion ( column , ColumnWidthOfRow ( row ) - 1 ) ; var nativeData = GetBlankExpansion ( row , ( permutedColumns . AnchorColumn == VirtualTreeConstant . NullIndex ) ? 0 : columnPermutation . GetNativeColumn ( permutedColumns . AnchorColumn ) , null ) ; return new BlankExpansionData ( nativeData . TopRow , permutedColumns . LeftColumn , nativeData . BottomRow , permutedColumns . RightColumn , permutedColumns . AnchorColumn ) ; } else { int topRow ; int leftColumn ; int bottomRow ; int rightColumn ; topRow = bottomRow = row ; leftColumn = rightColumn = column ; var localColumn = column ; var lastSubItem = false ; var pos = TrackCell ( row , ref localColumn , ref lastSubItem ) ; var lastNonBlankColumn = pos . ParentNode . GetColumnCount ( pos . Index ) - 1 ; var columnDiff = lastNonBlankColumn - localColumn ; var localColumnAdjusted = false ; var rowPadding = 0 ; if ( columnDiff <= 0 ) { var tn = pos . ParentNode ; var nextIndex = pos . Index ; var onLastItem = tn . InSubItemColumn ; while ( tn != null ) { if ( onLastItem ) { if ( nextIndex < ( tn . FullCount - 1 ) ) { onLastItem = false ; } else { nextIndex = tn . Index ; } } if ( tn . SubItemRoot ) { if ( tn . MultiColumn ) { tn = null ; } else { var subitemOwner = tn . Parent ; if ( onLastItem ) { rowPadding = subitemOwner . ImmedSubItemGain - tn . FullCount ; if ( tn . ComplexSubItem ) { ++ rowPadding ; } } lastNonBlankColumn = subitemOwner . Parent . GetColumnCount ( subitemOwner . Index ) - 1 ; columnDiff = lastNonBlankColumn - subitemOwner . FirstSubItem . ColumnOfRootNode ( tn ) ; if ( columnDiff <= 0 ) { tn = null ; } } break ; } tn = tn . Parent ; } if ( tn == null ) { if ( ! pos . ParentNode . InSubItemColumn ) { localColumn += columnDiff ; localColumnAdjusted = true ; } leftColumn += columnDiff ; rightColumn = ColumnCount - 1 ; } } var tnChild = pos . ParentNode . GetChildNode ( pos . Index ) ; if ( localColumn > 0 && tnChild != null ) { var sn = tnChild . SubItemAtColumn ( localColumn ) ; var tnSubItemRoot = ( sn == null ) ? null : sn . RootNode ; Debug . Assert ( tnChild == null || ! tnChild . ComplexSubItem ) ; if ( tnSubItemRoot != null && tnSubItemRoot . Expanded && tnSubItemRoot . FullCount > 0 ) { if ( localColumnAdjusted ) { var lastRowInCell = tnSubItemRoot . FullCount ; if ( tnSubItemRoot . ComplexSubItem ) { -- lastRowInCell ; } if ( pos . SubItemOffset >= lastRowInCell ) { topRow -= pos . SubItemOffset ; bottomRow = topRow + tnChild . ImmedSubItemGain ; topRow += lastRowInCell ; } tnChild = null ; } else { if ( pos . SubItemOffset > 0 ) { topRow -= pos . SubItemOffset ; bottomRow = topRow + tnChild . ImmedSubItemGain ; topRow += tnSubItemRoot . FullCount ; if ( tnSubItemRoot . ComplexSubItem ) { -- topRow ; } tnChild = null ; } } } } if ( tnChild != null ) { if ( pos . SubItemOffset > 0 ) { topRow -= pos . SubItemOffset ; bottomRow = topRow + tnChild . ImmedSubItemGain ; } else { bottomRow += tnChild . ImmedSubItemGain ; } } if ( rowPadding != 0 ) { bottomRow += rowPadding ; } return new BlankExpansionData ( topRow , leftColumn , bottomRow , rightColumn , leftColumn ) ; } }
For the given row and column, retrieve the range of cells that form the
blank region for the given items.
For the given row and column retrieve the range of cells that form the blank region for the given items .
// There is no way to get blank cells in a single-column tree // The consumer should not let the user do this but we need to handle it gracefully. // Make sure we have a row count by pulling the native row count from row 0 if the // row is fully blank, and from the native permutation column if it is not. // Get the row data from the native expansion and combine with the columns from // the permuted expansion. // Check the column range // Unfortunately, there is no easy check to see if we should apply this // column expansion or not. It should only be supplied if the node is a // child of either a complex sub item or the root node, not in other case. // While we're walking the loop, see if we're on the last cell // UNDONE_MC: Not sure about this one // We're looking at an expandable subitem. If this is in // the last column, then we need to expand to its right and treat // the parent node as the real owner. We're also in a perfect position // to see if we need extra row padding at the end. // Check the row range. Note that this does not depend on the column, // any column in the given column range provides the same answer. // A complex subitem should track to column 0 // We are in a region with subitems, but we hit to the // right of the last column, which happens to be expanded. // If the item is on or after // UNDONE_MC: This doesn't handle a multicolumn complex column
The expansion for this row and column
The expansion for this row and column
row
int
The row coordinate
The row coordinate
column
int
The column coordinate
The column coordinate
columnPermutation
ColumnPermutation
The column permutation to apply. If this
is provided, then column is relative to the column permutation, not
the unpermuted position.
The column permutation to apply . If this is provided then column is relative to the column permutation not the unpermuted position .