protected override VirtualTreeDisplayData GetDisplayData(int row, int column, VirtualTreeDisplayDataMasks requiredData)
        {
            var data = base.GetDisplayData(row, column, requiredData);
            if (column == 0)
            {
                data.Image = data.SelectedImage = MappingDetailsImages.ICONS_PROPERTY_KEY;
                data.ImageList = MappingDetailsImages.GetIconsImageList();
            }
            else if (column == 1)
            {
                data.Image = data.SelectedImage = MappingDetailsImages.ARROWS_BOTH;
                data.ImageList = MappingDetailsImages.GetArrowsImageList();
            }
            else if (column == 2)
            {
                if (_mappingAssociationSetEnd.ScalarProperties.Count > row
                    &&
                    _mappingAssociationSetEnd.ScalarProperties[row].ScalarProperty != null
                    &&
                    _mappingAssociationSetEnd.ScalarProperties[row].ScalarProperty.ColumnName.Status == BindingStatus.Known
                    &&
                    _mappingAssociationSetEnd.ScalarProperties[row].ScalarProperty.ColumnName.Target.IsKeyProperty)
                {
                    data.Image = data.SelectedImage = MappingDetailsImages.ICONS_COLUMN_KEY;
                }
                else
                {
                    data.Image = data.SelectedImage = MappingDetailsImages.ICONS_COLUMN;
                }
                data.ImageList = MappingDetailsImages.GetIconsImageList();
            }

            return data;
        }
        protected override VirtualTreeDisplayData GetDisplayData(int row, int column, VirtualTreeDisplayDataMasks requiredData)
        {
            var data = base.GetDisplayData(row, column, requiredData);
            if (column == 0)
            {
                if (_mappingColumnMappings.ScalarProperties.Count > row
                    && _mappingColumnMappings.ScalarProperties[row].IsKeyColumn)
                {
                    data.Image = data.SelectedImage = MappingDetailsImages.ICONS_COLUMN_KEY;
                }
                else
                {
                    data.Image = data.SelectedImage = MappingDetailsImages.ICONS_COLUMN;
                }
                data.ImageList = MappingDetailsImages.GetIconsImageList();
            }
            else if (column == 1)
            {
                data.Image = data.SelectedImage = MappingDetailsImages.ARROWS_BOTH;
                data.ImageList = MappingDetailsImages.GetArrowsImageList();
            }
            else if (column == 2)
            {
                // cache off the count
                var propertyCount = _mappingColumnMappings.ScalarProperties.Count;

                // cache off the property reference (if we have one)
                Property property = null;
                if (propertyCount > row
                    && _mappingColumnMappings.ScalarProperties[row].ScalarProperty != null
                    && _mappingColumnMappings.ScalarProperties[row].ScalarProperty.Name.Status == BindingStatus.Known)
                {
                    property = _mappingColumnMappings.ScalarProperties[row].ScalarProperty.Name.Target;
                }

                if (property != null
                    && property.IsKeyProperty)
                {
                    // if we have a valid property and its a key, show the key icon
                    data.Image = data.SelectedImage = MappingDetailsImages.ICONS_PROPERTY_KEY;
                }
                else if (property != null
                         && property.IsComplexTypeProperty)
                {
                    // if we have a valid property and its a complex property, show that one
                    data.Image = data.SelectedImage = MappingDetailsImages.ICONS_COMPLEX_PROPERTY;
                }
                else
                {
                    // in all other cases, show the default property icon
                    data.Image = data.SelectedImage = MappingDetailsImages.ICONS_PROPERTY;
                }

                // regardless, we use the same image list
                data.ImageList = MappingDetailsImages.GetIconsImageList();
            }

            return data;
        }
        protected override VirtualTreeDisplayData GetDisplayData(int row, int column, VirtualTreeDisplayDataMasks requiredData)
        {
            var data = base.GetDisplayData(row, column, requiredData);
            if (column == 0)
            {
                var scalarProperty = row < ElementCount
                                         ? GetElement(row) as MappingFunctionImportScalarProperty
                                         : null;
                if (scalarProperty != null
                    && scalarProperty.IsKeyProperty)
                {
                    data.Image = data.SelectedImage = MappingDetailsImages.ICONS_PROPERTY_KEY;
                }
                else
                {
                    data.Image = data.SelectedImage = MappingDetailsImages.ICONS_PROPERTY;
                }
                data.ImageList = MappingDetailsImages.GetIconsImageList();
            }
            else if (column == 1)
            {
                data.Image = data.SelectedImage = MappingDetailsImages.ARROWS_LEFT;
                data.ImageList = MappingDetailsImages.GetArrowsImageList();
            }
            else if (column == 2)
            {
                data.Image = data.SelectedImage = MappingDetailsImages.ICONS_COLUMN;
                data.ImageList = MappingDetailsImages.GetIconsImageList();

                var scalarProperty = row < ElementCount
                                         ? GetElement(row) as MappingFunctionImportScalarProperty
                                         : null;
                if (scalarProperty != null
                    && (scalarProperty.ModelItem == null || scalarProperty.IsComplexProperty))
                {
                    // gray out the text if it's default value or error message
                    data.GrayText = true;
                }
            }

            return data;
        }
        protected override VirtualTreeDisplayData GetDisplayData(int row, int column, VirtualTreeDisplayDataMasks requiredData)
        {
            var data = base.GetDisplayData(row, column, requiredData);
            if (column == 0)
            {
                data.Image = data.SelectedImage = MappingDetailsImages.ICONS_CONDITION;
                data.ImageList = MappingDetailsImages.GetIconsImageList();
            }
            if (column == 2)
            {
                // if the value of condition is empty string we want to show gray text "<Emtpy String>" instead
                var mc = GetElement(row) as MappingCondition;
                if (mc != null
                    && mc.IsValueEmptyString)
                {
                    data.GrayText = true;
                }
            }

            return data;
        }
        protected override VirtualTreeDisplayData GetDisplayData(int row, int column, VirtualTreeDisplayDataMasks requiredData)
        {
            var data = base.GetDisplayData(row, column, requiredData);
            if (column == 0)
            {
                data.Image = data.SelectedImage = MappingDetailsImages.ICONS_RESULT_BINDING;
                data.ImageList = MappingDetailsImages.GetIconsImageList();
            }
            else if (column == 1)
            {
                data.Image = data.SelectedImage = MappingDetailsImages.ARROWS_RIGHT;
                data.ImageList = MappingDetailsImages.GetArrowsImageList();
            }
            else if (column == 2)
            {
                if (_mappingResultBindings.ResultBindings.Count > row
                    && _mappingResultBindings.ResultBindings[row].ResultBinding != null
                    && _mappingResultBindings.ResultBindings[row].ResultBinding.Name.Status == BindingStatus.Known
                    && _mappingResultBindings.ResultBindings[row].ResultBinding.Name.Target.IsKeyProperty)
                {
                    data.Image = data.SelectedImage = MappingDetailsImages.ICONS_PROPERTY_KEY;
                }
                else
                {
                    data.Image = data.SelectedImage = MappingDetailsImages.ICONS_PROPERTY;
                }
                data.ImageList = MappingDetailsImages.GetIconsImageList();
            }

            return data;
        }
 VirtualTreeDisplayData IBranch.GetDisplayData(int row, int column, VirtualTreeDisplayDataMasks requiredData)
 {
     return GetDisplayData(row, column, requiredData);
 }
        /// <summary>
        ///     Returns structure describing how this branch should be displayed.
        /// </summary>
        /// <param name="row">Index into this branch</param>
        /// <param name="column">Column index</param>
        /// <param name="requiredData">The data that must be filled in</param>
        /// <returns>
        ///     Structure to be filled with display information.  By default,
        ///     No icon is specified, and read-only and creator nodes are grayed out.
        /// </returns>
        protected virtual VirtualTreeDisplayData GetDisplayData(int row, int column, VirtualTreeDisplayDataMasks requiredData)
        {
            var data = new VirtualTreeDisplayData(-1);

            // account for row insertion index
            if (_insertingIndex != -1
                && row > _insertingIndex)
            {
                row--;
            }

            var count = ElementCount;

            if ((requiredData.Mask & VirtualTreeDisplayMasks.StateImage) != 0
                && row < count)
            {
                var columnDescriptor = _columns[column];

                if (columnDescriptor.ColumnIsCheckBox)
                {
                    var checkState = columnDescriptor.GetCheckBoxValue(GetElement(row));

                    if (checkState != CheckBoxState.Unsupported)
                    {
                        // set state index
                        data.StateImageIndex = (short)checkState;
                    }
                }
            }

            if (row >= count)
            {
                // display creator nodes in gray
                data.GrayText = true;
            }
            else if (_lastText != null
                     && _lastText.Length > 0)
            {
                // use lastText here as an optimization.  If there's no text, there's no
                // reason to call derived classes to check the value, as GrayText setting is
                // irrelevant
                var supportedState = GetValueSupported(row, column);
                // display non-editable nodes in gray
                if ((supportedState & TreeGridDesignerValueSupportedStates.DisplayReadOnly) != 0)
                {
                    data.GrayText = true;
                }
            }
            return data;
        }
        protected override VirtualTreeDisplayData GetDisplayData(int row, int column, VirtualTreeDisplayDataMasks requiredData)
        {
            var data = base.GetDisplayData(row, column, requiredData);

            // construct underlying parameter
            Parameter param = null;
            if (row < ElementCount)
            {
                var mfsp = GetElement(row) as MappingFunctionScalarProperty;
                if (null != mfsp)
                {
                    param = mfsp.StoreParameter;
                }
            }

            if (column == 0)
            {
                data.Image = data.SelectedImage = MappingDetailsImages.ICONS_PARAMETER;
                data.ImageList = MappingDetailsImages.GetIconsImageList();
            }
            else if (column == 1)
            {
                // direction of arrow icon depends on InOut of underlying parameter
                if (null != param
                    && Parameter.InOutMode.Out == param.InOut)
                {
                    data.Image = data.SelectedImage = MappingDetailsImages.ARROWS_RIGHT;
                }
                else if (null != param
                         && Parameter.InOutMode.InOut == param.InOut)
                {
                    data.Image = data.SelectedImage = MappingDetailsImages.ARROWS_BOTH;
                }
                else
                {
                    data.Image = data.SelectedImage = MappingDetailsImages.ARROWS_LEFT;
                }
                data.ImageList = MappingDetailsImages.GetArrowsImageList();
            }
            else if (column == 2)
            {
                // do not show icon for Out parameters
                if (null != param
                    && Parameter.InOutMode.Out != param.InOut)
                {
                    if (_mappingFunctionScalarProperties.ScalarProperties.Count > row
                        && _mappingFunctionScalarProperties.ScalarProperties[row].ScalarProperty != null
                        && _mappingFunctionScalarProperties.ScalarProperties[row].ScalarProperty.Name.Status == BindingStatus.Known
                        && _mappingFunctionScalarProperties.ScalarProperties[row].ScalarProperty.Name.Target.IsKeyProperty)
                    {
                        data.Image = data.SelectedImage = MappingDetailsImages.ICONS_PROPERTY_KEY;
                    }
                    else
                    {
                        data.Image = data.SelectedImage = MappingDetailsImages.ICONS_PROPERTY;
                    }
                    data.ImageList = MappingDetailsImages.GetIconsImageList();
                }
            }

            return data;
        }
 /// <summary>
 ///     Compare two VirtualTreeDisplayDataMasks structures
 /// </summary>
 /// <param name="operand1">Left operand</param>
 /// <param name="operand2">Right operand</param>
 /// <returns>true if operands are equal</returns>
 public static bool Compare(VirtualTreeDisplayDataMasks operand1, VirtualTreeDisplayDataMasks operand2)
 {
     return operand1.myMask == operand2.myMask && operand1.myStateMask == operand2.myStateMask;
 }
示例#10
0
        /// <summary>
        ///     Retrieves display data for the header row.
        /// </summary>
        protected virtual VirtualTreeDisplayData GetDisplayData(int row, int column, VirtualTreeDisplayDataMasks requiredData)
        {
            var data = new VirtualTreeDisplayData(-1);

            if (column == 0)
            {
                data.Bold = true;
            }

            if ((requiredData.Mask & VirtualTreeDisplayMasks.StateImage) != 0
                && row < _currentBranches.Count)
            {
                var columnDescriptor = _columns[column];

                if (columnDescriptor.ColumnIsCheckBox)
                {
                    var checkState = GetCheckBoxValue(row, column);

                    if (checkState != CheckBoxState.Unsupported)
                    {
                        // set state index
                        data.StateImageIndex = (short)checkState;
                    }
                }
            }

            return data;
        }
示例#11
0
 VirtualTreeDisplayData IBranch.GetDisplayData(int row, int column, VirtualTreeDisplayDataMasks requiredData)
 {
     var branch = FindBranchForRow(ref row);
     return branch.GetDisplayData(row, column, requiredData);
 }
        protected override VirtualTreeDisplayData GetDisplayData(int row, int column, VirtualTreeDisplayDataMasks requiredData)
        {
            var data = base.GetDisplayData(row, column, requiredData);
            if (column == 0)
            {
                data.Image = data.SelectedImage = MappingDetailsImages.ICONS_FOLDER;
                data.ImageList = MappingDetailsImages.GetIconsImageList();
            }

            return data;
        }
示例#13
0
 /// <summary>
 ///     Compare two VirtualTreeDisplayDataMasks structures
 /// </summary>
 /// <param name="operand1">Left operand</param>
 /// <param name="operand2">Right operand</param>
 /// <returns>true if operands are equal</returns>
 public static bool Compare(VirtualTreeDisplayDataMasks operand1, VirtualTreeDisplayDataMasks operand2)
 {
     return(operand1.myMask == operand2.myMask && operand1.myStateMask == operand2.myStateMask);
 }
        private int ListItemStringWidth(Graphics graphics, ref VirtualTreeItemInfo info, string alternateText, out int imageWidth)
        {
            imageWidth = 0;
            var tddMasks = new VirtualTreeDisplayDataMasks(VirtualTreeDisplayMasks.State, VirtualTreeDisplayStates.Bold);
            var fCheckImage = myImageWidth > 0;
            var fCheckState = myStateImageWidth > 0;
            if (fCheckImage)
            {
                tddMasks.Mask |= VirtualTreeDisplayMasks.Image;
            }
            if (fCheckState)
            {
                tddMasks.Mask |= VirtualTreeDisplayMasks.StateImage;
            }
            var tdd = info.Branch.GetDisplayData(info.Row, info.Column, tddMasks);
            var font = (0 == (tdd.State & VirtualTreeDisplayStates.Bold)) ? Font : BoldFont;

            int retVal;
            if (alternateText == null)
            {
                retVal = ListItemStringWidth(
                    graphics,
                    font,
                    ref info);
            }
            else
            {
                retVal = ListItemStringWidth(
                    graphics,
                    font,
                    alternateText);
            }
            if (fCheckImage && tdd.Image != -1)
            {
                imageWidth += myImageWidth;
            }
            if (fCheckState && tdd.StateImageIndex >= 0)
            {
                imageWidth += myStateImageWidth;
            }
            return retVal;
        }
        private void DoDrawItem(
            DrawItemEventArgs e, int column, int nativeColumn, bool windowFocused, bool itemFocused, bool columnSelected,
            bool dontDrawLeadingGridline, bool trailingColumn, Rectangle itemBounds)
        {
            Debug.Assert(Redraw && myUpdateCount == 0); // Handled very early in WmReflectDrawItem
            if (e.Index == -1)
            {
                return; // UNDONE: Draw focus rect in empty list
            }

            var drawingEditCell = GetStateFlag(VTCStateFlags.LabelEditActive) && myInPlaceControl != null && e.Index == myEditIndex
                                  && (myMctree == null || columnSelected);
            var drawFullEditCell = drawingEditCell && GetStateFlag(VTCStateFlags.LabelEditTransparent);
            var ignoreSelection = !Enabled || (!columnSelected && (!MultiColumnHighlight || (drawingEditCell && !drawFullEditCell)));
            // When MultiColumnHightlight is set, the focus rect should always be drawn.  This is because there is no other
            // way to indicate the currently focused column.  Otherwise, we respect the system setting to draw the focus rectangle
            var drawFocusRect = columnSelected && itemFocused && (MultiColumnHighlight || (e.State & DrawItemState.NoFocusRect) == 0);

            var info = myTree.GetItemInfo(e.Index, nativeColumn, true);
            var expandable = HasButtons && info.Expandable;
            var expanded = expandable && info.Expanded;
            var selected = !ignoreSelection && SelectionMode != SelectionMode.None
                           && (e.State & DrawItemState.Selected) == DrawItemState.Selected;

            // Setup text font, color, and text
            var itemBackColor = selected ? SelectedItemActiveBackColor : e.BackColor;
            var itemForeColor = selected ? SelectedItemActiveForeColor : e.ForeColor;
            var trailingRectBackColor = itemBackColor; // color used for filling trailing space in the control after the last column
            var controlBackColor = BackColor;
            Brush controlBackBrush = null;
            Brush itemBackBrush = null;
            Brush itemForeBrush = null;
            Brush trailingRectBackBrush = null;

            if (ignoreSelection && (e.State & DrawItemState.Selected) != 0)
            {
                itemBackColor = trailingRectBackColor = controlBackColor;
                itemForeColor = ForeColor;
            }
            // Draw the background of the focused cell with the control's background and foreground colors when
            // MultiColumnHighlight and DistinguishFocusedColumn are set.  This makes distinguishing the focused cell much easier.
            if (drawFocusRect
                && MultiColumnHighlight
                && DistinguishFocusedColumn)
            {
                itemBackColor = controlBackColor; // don't set trailingRectBackColor here
                itemForeColor = ForeColor;
            }
            // Don't draw with a gray brush if selected, as this can obscure the text.
            if (!Enabled
                && !selected)
            {
                itemForeColor = DisabledItemForeColor;
            }

            var branch = info.Branch;
            var text = info.Blank ? null : branch.GetText(info.Row, info.Column);
            if (text == null)
            {
                text = string.Empty;
            }

            //Debug.WriteLine(text + " " + myXPos.ToString() + " " + e.Bounds.Left.ToString());
            //			bool expandable =
            //				HasButtons &&
            //				(0 == (branch.Flags & BranchFeatures.NoExpansion)) && 
            //				branch.IsExpandable(relIndex);
            //			bool expanded = expandable && helper.IsExpanded(e.Index);

            VirtualTreeDisplayData tdd;
            var drawStateImage = false;
            if (info.Blank)
            {
                var expansion = myTree.GetBlankExpansion(e.Index, column, myColumnPermutation);
                var anchorInfo = myTree.GetItemInfo(expansion.TopRow, expansion.AnchorColumn, false);
                tdd = VirtualTreeDisplayData.Empty;
                var tddMasks = new VirtualTreeDisplayDataMasks(
                    VirtualTreeDisplayMasks.Image |
                    VirtualTreeDisplayMasks.ImageOverlays |
                    VirtualTreeDisplayMasks.State |
                    VirtualTreeDisplayMasks.SelectedImage,
                    0);
                if (expanded)
                {
                    tddMasks.StateMask |= VirtualTreeDisplayStates.Expanded;
                }
                if (selected)
                {
                    tddMasks.StateMask |= VirtualTreeDisplayStates.Selected;
                }
                drawStateImage = myStateImageList != null || GetStyleFlag(VTCStyleFlags.StandardCheckBoxes);
                if (drawStateImage)
                {
                    tddMasks.Mask |= VirtualTreeDisplayMasks.StateImage;
                }
                tdd = anchorInfo.Branch.GetDisplayData(anchorInfo.Row, anchorInfo.Column, tddMasks);
            }
            else
            {
                var tddMasks = new VirtualTreeDisplayDataMasks(
                    VirtualTreeDisplayMasks.Image |
                    VirtualTreeDisplayMasks.ImageOverlays |
                    VirtualTreeDisplayMasks.State |
                    VirtualTreeDisplayMasks.SelectedImage |
                    VirtualTreeDisplayMasks.ForceSelect |
                    VirtualTreeDisplayMasks.Color,
                    VirtualTreeDisplayStates.Cut |
                    VirtualTreeDisplayStates.GrayText |
                    VirtualTreeDisplayStates.Bold |
                    VirtualTreeDisplayStates.TextAlignFar);
                if (expanded)
                {
                    tddMasks.StateMask |= VirtualTreeDisplayStates.Expanded;
                }
                if (selected)
                {
                    tddMasks.StateMask |= VirtualTreeDisplayStates.Selected;
                }
                drawStateImage = myStateImageList != null || GetStyleFlag(VTCStyleFlags.StandardCheckBoxes);
                if (drawStateImage)
                {
                    tddMasks.Mask |= VirtualTreeDisplayMasks.StateImage;
                }
                tdd = branch.GetDisplayData(info.Row, info.Column, tddMasks);

                if (tdd.GrayText
                    && !selected)
                {
                    itemForeColor = DisabledItemForeColor;
                }
            }

            if (tdd.ImageList == null)
            {
                if (myImageList != null
                    && tdd.Image != -1)
                {
                    tdd.ImageList = myImageList;
                }
            }
            else if (myImageList == null)
            {
                ImageList = tdd.ImageList;
            }

            var font = (0 == (tdd.State & VirtualTreeDisplayStates.Bold)) ? e.Font : BoldFont;

            // Note that DrawItemEventArgs already contain SystemColors.Highlight and
            // SystemColors.HighlightText if the item is marked as selected. Otherwise,
            // we would switch to those colors here. However, DrawItemEventArgs does
            // not automatically do a 'selected but not focused' color, so we need
            // to do that explicitly at this point.
            if (selected)
            {
                if (!itemFocused
                    && !drawFullEditCell
                    &&
                    // Make sure multiselect items are drawn the correct color when they
                    // don't have the focus.
                    (!windowFocused || SelectionMode == SelectionMode.One)
                    &&
                    // Don't switch to gray if the gray color is the same as the
                    // window background color
                    SystemColors.Control.ToArgb() != SystemColors.Window.ToArgb())
                {
                    itemForeColor = SelectedItemInactiveForeColor;
                    itemBackColor = SelectedItemInactiveBackColor;
                    if (MultiColumnHighlight)
                    {
                        // trailing rect should match the item if we're drawing selection in all columns
                        trailingRectBackColor = itemBackColor;
                    }
                }
            }
            else
            {
                // Selection color overrides back color specified by the branch
                // Since colors are always paired, selection also needs to override the
                // forecolor provided by the branch.
                if (tdd.ForeColor != Color.Empty)
                {
                    itemForeColor = tdd.ForeColor;
                }

                if (tdd.BackColor != Color.Empty)
                {
                    itemBackColor = tdd.BackColor;
                }
            }

            // Highlight the current drop target.  Do this after the block above since we want to use the
            // highlight color in this case even if the window doesn't have focus (follows Windows tree control behavior).
            if (myDropRow != VirtualTreeConstant.NullIndex
                && myDropRow == e.Index
                && GetStateFlag(VTCStateFlags.DragDropHighlight)
                && (myDropColumn == nativeColumn || MultiColumnHighlight))
            {
                selected = true;
                ignoreSelection = false;
                itemBackColor = trailingRectBackColor = SelectedItemActiveBackColor;
                itemForeColor = SelectedItemActiveForeColor;
            }

            var bounds = itemBounds;
            var graphics = e.Graphics;
            var adjustedItemHeight = myItemHeight; // we adjust this value for gridlines later on
            Pen gridPen = null;
            if (HasHorizontalGridLines || HasVerticalGridLines)
            {
                var gridLineColor = GridLinesColor;
                gridPen = new Pen(gridLineColor);
                // each row is responsible for drawing the bottom horizontal gridline only.
                if (HasHorizontalGridLines)
                {
                    if (info.TrailingItem)
                    {
                        graphics.DrawLine(gridPen, bounds.X, bounds.Bottom - 1, bounds.Right, bounds.Bottom - 1);

                        // draw horizontal gridlines the full width of the control.
                        if (trailingColumn && e.Bounds.Right > bounds.Right)
                        {
                            graphics.DrawLine(gridPen, bounds.Right, bounds.Bottom - 1, e.Bounds.Right, bounds.Bottom - 1);
                        }
                    }
                    --adjustedItemHeight;
                    bounds.Height -= 1;
                }

                // draw vertical gridline, except in the first column, where we never draw the vertical gridline.
                if (HasVerticalGridLines
                    && column > 0
                    && !dontDrawLeadingGridline)
                {
                    graphics.DrawLine(gridPen, bounds.X, bounds.Y - 1, bounds.X, bounds.Bottom - 1);
                    bounds.X += 1;
                    bounds.Width -= 1;
                }
            }
            var remainingWidth = bounds.Width;

            // Move the graphics object to the correct location
            var graphicsContainer = graphics.BeginContainer();
            try
            {
                graphics.TranslateTransform(bounds.Left, bounds.Top);

                //
                // Draw the item
                //

                // Split indent bitmap drawing into a helper function to prevent > 64 locals in one function (FxCop violation)
                var textLeft = 0;
                DrawIndentLines(
                    graphics, itemBackColor, itemForeColor, e.Index, nativeColumn, info, tdd, remainingWidth, adjustedItemHeight,
                    ref textLeft);

                if (textLeft != 0)
                {
                    graphics.TranslateTransform(textLeft, 0);
                    remainingWidth -= textLeft;
                }

                if (drawStateImage
                    && tdd.StateImageIndex >= 0
                    && remainingWidth > 0)
                {
                    ImageList stateImages = null;
                    if (tdd.StateImageList == null)
                    {
                        stateImages = StateImageList; // Force creation if delayed
                    }
                    else if (myStateImageList == null)
                    {
                        stateImages = tdd.StateImageList;
                        StateImageList = stateImages;
                    }

                    // Paint the state image background same as the item background.
                    EnsureBrush(ref itemBackBrush, itemBackColor);
                    graphics.FillRectangle(itemBackBrush, 0, 0, myStateImageWidth, adjustedItemHeight);

                    var xOffset = (int)graphics.Transform.OffsetX;
                    var yOffset = ((int)graphics.Transform.OffsetY) + (adjustedItemHeight - myImageHeight + 1) / 2;

                    int stateImageIndex = tdd.StateImageIndex;
                    if (myMouseOverIndex == e.Index
                        && myMouseOverColumn == nativeColumn
                        && GetStateFlag(VTCStateFlags.StateImageHotTracked)
                        && (stateImageIndex == (int)StandardCheckBoxImage.Unchecked
                            || stateImageIndex == (int)StandardCheckBoxImage.Checked
                            || stateImageIndex == (int)StandardCheckBoxImage.Indeterminate))
                    {
                        stateImageIndex++; // hot-tracked images appear immediately after the regular versions in the image list.
                    }
                    stateImages.Draw(graphics, xOffset, yOffset, stateImageIndex);
                    graphics.TranslateTransform(myStateImageWidth, 0);
                    remainingWidth -= myStateImageWidth;
                }

                if (tdd.ImageList != null
                    && remainingWidth > 0
                    && !info.Blank)
                {
                    if (tdd.Image != -1)
                    {
                        // Paint the item image background same as the item background.
                        EnsureBrush(ref itemBackBrush, itemBackColor);
                        graphics.FillRectangle(itemBackBrush, 0, 0, myImageWidth, adjustedItemHeight);

                        DoDrawImageAndOverlays(graphics, tdd, adjustedItemHeight, selected, controlBackColor);
                    }
                    graphics.TranslateTransform(myImageWidth, 0);
                    remainingWidth -= myImageWidth;
                }

                if (remainingWidth > 0)
                {
                    var textBounds = new Rectangle(0, 0, remainingWidth, bounds.Height);
                    var gridWidth = remainingWidth;
                    if (drawingEditCell && !drawFullEditCell)
                    {
                        // Just blank the rest of the item. This allows us to
                        // not worry about the width of the contents of the label edit
                        // box, which in turn enables custom input in that window.
                        EnsureBrush(ref controlBackBrush, controlBackColor);
                        graphics.FillRectangle(controlBackBrush, textBounds);
                    }
                    else
                    {
                        var border = 1;
                        //int height = Font.Height + 2 * border;

                        // Due to some sort of unpredictable painting optimization in the Windows ListBox control,
                        // we need to always paint the background rectangle for the current line.
                        EnsureBrush(ref itemBackBrush, itemBackColor);
                        EnsureBrush(ref itemForeBrush, itemForeColor);
                        var paintBackground = true;
                        if (FullCellSelect || MultiColumnHighlight)
                        {
                            paintBackground = false;
                            graphics.FillRectangle(itemBackBrush, textBounds);
                        }

                        // Draw the text
                        //
                        var stringBounds = new Rectangle(
                            textBounds.X + 1,
                            textBounds.Y + border,
                            textBounds.Width - 1,
                            textBounds.Height - border * 2);

                        var format = StringFormat;
                        format.Alignment = GetLabelTextAlignment(ref tdd);

                        var drawFocusRectForEmptyItem = false;

                        if (text.Length == 0
                            && itemFocused
                            && columnSelected)
                        {
                            // make sure to draw focus if there is no text for the item, otherwise we
                            // end up with absolutely no visual indication for the current selection
                            drawFocusRect = drawFocusRectForEmptyItem = true;
                        }

                        // Do actual drawing
                        if (paintBackground && (drawFocusRect || selected))
                        {
                            int stringWidth;
                            if (text.Length > 0)
                            {
                                // Add one so potential focus rect doesn't touch the edge of the text
                                stringWidth =
                                    StringRenderer.MeasureString(
                                        UseCompatibleTextRendering, graphics, text, font,
                                        new Rectangle(textBounds.Location, textBounds.Size), format).Width + 1;
                            }
                            else
                            {
                                stringWidth = -1;
                            }

                            Debug.Assert(textBounds.Left == 0);
                            if ((stringWidth + stringBounds.Left) < textBounds.Width)
                            {
                                // Blit the end clean and the part under the string with the background brush
                                var trailingRect = textBounds;
                                trailingRect.X = stringBounds.Left + stringWidth;
                                if (selected)
                                {
                                    EnsureBrush(ref controlBackBrush, controlBackColor);
                                    graphics.FillRectangle(controlBackBrush, trailingRect);
                                    if (text.Length > 0
                                        || (!info.Blank && GetStyleFlag(VTCStyleFlags.MultiSelect)))
                                        // avoid drawing text selection highlight if there's no text
                                    {
                                        if (trailingRect.Left > 0)
                                        {
                                            textBounds.Width = trailingRect.Left;
                                        }
                                        graphics.FillRectangle(itemBackBrush, textBounds);
                                    }
                                }
                                else
                                {
                                    graphics.FillRectangle(itemBackBrush, textBounds);
                                    if (trailingRect.Left > 0)
                                    {
                                        textBounds.Width = trailingRect.Left;
                                    }
                                }
                                paintBackground = false;
                            }
                        }

                        // Default processing for the previous block
                        if (paintBackground)
                        {
                            // Blit the whole thing
                            graphics.FillRectangle(itemBackBrush, textBounds);
                        }

                        // ensure that we use the full item width to bound the text rectangle, to avoid clipping if we're using ellipsis string trimming (VSW 371458).
                        StringRenderer.DrawString(
                            UseCompatibleTextRendering, graphics, text, font, itemForeBrush, itemForeColor,
                            new Rectangle(textBounds.Left, textBounds.Top, remainingWidth, textBounds.Height), format);

                        // Draw the focus rect if required
                        //
                        if (drawFocusRect)
                        {
                            // Don't allow the right edge of the focus rectangle to touch the edge of the client area.  If the control resizes or is scrolled,
                            // and the size of the focus rectangle changes, the right edge may not be invalidated, leaving an artifact.  This problem does not
                            // occur if the header control is present (more of the control is invalidated when header size changes).
                            if (trailingColumn
                                && (myHeaderContainer == null || !myHeaderContainer.Visible)
                                && itemBounds.Right == (ClientSize.Width + myXPos))
                            {
                                textBounds.Width++;
                            }
                            if (selected
                                && MultiColumnHighlight
                                && DistinguishFocusedColumn
                                && e.Index == CaretIndex)
                            {
                                // Draw special focus rectangle for selected, focused cells when MultiColumnHighlight is set.
                                // See VSW 399853.
                                DrawFocusRectangleForMultiColumnHighlight(graphics, textBounds);
                            }
                            else
                            {
                                ControlPaint.DrawFocusRectangle(
                                    graphics, textBounds, itemForeColor, drawFocusRectForEmptyItem ? controlBackColor : itemBackColor);
                            }
                        }
                    }

                    // If we're the last cell in a fixed width column, then there may
                    // be space to the right and we need to draw a trailing vertical gridline
                    if (trailingColumn && e.Bounds.Right > bounds.Right)
                    {
                        if (HasVerticalGridLines)
                        {
                            graphics.DrawLine(gridPen, gridWidth, -1, gridWidth, textBounds.Bottom);
                        }

                        // fill the rest of the row with the appropriate color
                        EnsureBrush(ref trailingRectBackBrush, trailingRectBackColor);
                        graphics.FillRectangle(trailingRectBackBrush, gridWidth + 1, 0, e.Bounds.Right - bounds.Right, bounds.Height);
                    }
                }
            }
            finally
            {
                graphics.EndContainer(graphicsContainer); // Put this back before deferring to base
                CleanBrush(ref controlBackBrush, controlBackColor);
                CleanBrush(ref itemBackBrush, itemBackColor);
                CleanBrush(ref itemForeBrush, itemForeColor);
                CleanBrush(ref trailingRectBackBrush, trailingRectBackColor);
            }
        }
        private VirtualTreeHitInfo HitInfo(int x, int y, out ExtraHitInfo extraInfo, bool populateExtras)
        {
            extraInfo = new ExtraHitInfo();
            var target = VirtualTreeHitTargets.Uninitialized;
            var absIndex = VirtualTreeConstant.NullIndex;
            var column = 0;
            var nativeColumn = 0;
            var rawRow = absIndex;
            var rawColumn = absIndex;

            if (x < 0)
            {
                target |= VirtualTreeHitTargets.ToLeft;
            }
            else if (x > ClientSize.Width)
            {
                target |= VirtualTreeHitTargets.ToRight;
            }

            if (y < 0)
            {
                target |= VirtualTreeHitTargets.Above;
            }
            else if (y > ClientSize.Height)
            {
                target |= VirtualTreeHitTargets.Below;
            }
            if (target != VirtualTreeHitTargets.Uninitialized)
            {
                return new VirtualTreeHitInfo(absIndex, column, target);
            }

            absIndex = rawRow = IndexFromPoint(x, y);

            if ((absIndex < 0)
                ||
                (myTree == null)
                ||
                (absIndex >= myTree.VisibleItemCount))
            {
                return new VirtualTreeHitInfo(VirtualTreeConstant.NullIndex, column, VirtualTreeHitTargets.NoWhere);
            }

            // Shift by the horizontal scroll position
            var scrollShift = myXPos;
            x += scrollShift;

            // Determine the current column
            int level;
            int relIndex;
            IBranch branch;
            var multiColumn = myMctree != null;
            var labelShift = 0;
            int itemWidth;
            int itemLeft;
            if (multiColumn)
            {
                column = rawColumn = ColumnHitTest(x, out itemLeft, out itemWidth);
                int columns;
                if (myColumnPermutation == null)
                {
                    columns = myMctree.ColumnCount;
                    nativeColumn = column;
                }
                else
                {
                    columns = myColumnPermutation.VisibleColumnCount;
                    nativeColumn = myColumnPermutation.GetNativeColumn(column);
                }
                if (column >= columns)
                {
                    return new VirtualTreeHitInfo(VirtualTreeConstant.NullIndex, column, VirtualTreeHitTargets.NoWhere);
                }
            }
            else
            {
                itemLeft = 0;
                itemWidth = ClientSize.Width;
            }
            var leadingBlanksLeft = itemLeft;
            var checkRootLines = GetAnyStyleFlag(VTCStyleFlags.HasRootLines | VTCStyleFlags.HasRootButtons);
            var info = myTree.GetItemInfo(absIndex, nativeColumn, checkRootLines && nativeColumn > 0);
            VirtualTreeHitTargets blankTargetBit = 0;
            var testingBlank = info.Blank;
            if (multiColumn)
            {
                var expansion = myTree.GetBlankExpansion(absIndex, column, myColumnPermutation);
                //Debug.WriteLine(string.Format("Left/Top ({0}, {1}) Anchor ({2}, {3}) Width {4} Height {5}", expansion.LeftColumn, expansion.TopRow, expansion.AnchorColumn, expansion.TopRow, expansion.Width, expansion.Height));
                if (expansion.AnchorColumn != VirtualTreeConstant.NullIndex)
                {
                    if (testingBlank)
                    {
                        blankTargetBit = VirtualTreeHitTargets.OnBlankItem;
                        absIndex = expansion.TopRow;
                        column = expansion.AnchorColumn;
                        nativeColumn = (myColumnPermutation == null) ? column : myColumnPermutation.GetNativeColumn(column);
                        // If the expansion width is 1, then we're in a blank expansion below
                        // the last item in a column. Treat/ this the same as hovering on the
                        // main item, except that we don't acknowledge glyph or button hovers.
                        info = myTree.GetItemInfo(absIndex, nativeColumn, checkRootLines && nativeColumn > 0);
                    }
                    if (expansion.Width > 1)
                    {
                        // The item is wider than a single column. This type of item
                        // always extends the full width of the tree. Retrieve new information.
                        GetColumnBounds(expansion.LeftColumn, expansion.RightColumn, out itemLeft, out itemWidth);
                        leadingBlanksLeft = itemLeft;
                        if (expansion.LeftColumn != expansion.AnchorColumn)
                        {
                            GetColumnBounds(expansion.AnchorColumn, expansion.RightColumn, out itemLeft, out itemWidth);
                        }
                    }
                }
            }
            if (info.Blank)
            {
                return new VirtualTreeHitInfo(rawRow, rawColumn, VirtualTreeHitTargets.OnBlankItem);
            }
            else if (itemLeft != leadingBlanksLeft
                     && x < itemLeft)
            {
                return new VirtualTreeHitInfo(
                    absIndex, column, nativeColumn, rawRow, rawColumn, VirtualTreeHitTargets.OnItemLeft | blankTargetBit);
            }

            level = info.Level;
            branch = info.Branch;
            relIndex = info.Row;

            // Shift by the indent width
            var xItemStart = level * myIndentWidth + itemLeft;
            if (checkRootLines && (nativeColumn == 0 || !info.SimpleCell))
            {
                xItemStart += myIndentWidth;
            }

            if (x < xItemStart)
            {
                // We're in the indent region
                target = VirtualTreeHitTargets.OnItemIndent;

                // See if we're actually on a button, not just an indent
                if (HasButtons && ((x + myIndentWidth) > xItemStart))
                {
                    if (myTree.IsExpandable(absIndex, nativeColumn))
                    {
                        target = VirtualTreeHitTargets.OnItemButton;
                    }
                }
                //UNDONE Find the item whose expansion we're clicking on, and check whether
                //or not we're within the bounds of the button width of the item.
                return new VirtualTreeHitInfo(absIndex, column, nativeColumn, rawRow, rawColumn, target | blankTargetBit);
            }
            else
            {
                x -= xItemStart;
                var tddMasks = new VirtualTreeDisplayDataMasks(
                    VirtualTreeDisplayMasks.State, VirtualTreeDisplayStates.Bold | VirtualTreeDisplayStates.TextAlignFar);
                if (myImageWidth > 0)
                {
                    tddMasks.Mask |= VirtualTreeDisplayMasks.Image;
                }
                if (myStateImageWidth > 0)
                {
                    tddMasks.Mask |= VirtualTreeDisplayMasks.StateImage;
                }
                var tdd = branch.GetDisplayData(relIndex, info.Column, tddMasks);

                // Check if we're on the state icon.
                if (myStateImageWidth > 0)
                {
                    if (tdd.StateImageIndex >= 0)
                    {
                        if (x < myStateImageWidth)
                        {
                            target = VirtualTreeHitTargets.OnItemStateIcon;

                            if (StandardCheckBoxes
                                && tdd.StateImageList == null
                                &&
                                (tdd.StateImageIndex == (int)StandardCheckBoxImage.Unchecked
                                 || tdd.StateImageIndex == (int)StandardCheckBoxImage.Checked
                                 || tdd.StateImageIndex == (int)StandardCheckBoxImage.Indeterminate))
                            {
                                target |= VirtualTreeHitTargets.StateIconHotTracked;
                            }
                        }
                        else
                        {
                            x -= myStateImageWidth;
                        }
                        labelShift += myStateImageWidth;
                    }
                }

                // Check if we're on the image icon
                if (myImageWidth > 0)
                {
                    if (tdd.Image != -1)
                    {
                        if (x < myImageWidth)
                        {
                            if (target == VirtualTreeHitTargets.Uninitialized)
                            {
                                target = VirtualTreeHitTargets.OnItemIcon;
                            }
                        }
                        else
                        {
                            x -= myImageWidth;
                        }
                        labelShift += myImageWidth;
                    }
                }

                if (populateExtras || target == VirtualTreeHitTargets.Uninitialized)
                {
                    // See where we are on the item's label
                    var labelFont = (0 == (tdd.State & VirtualTreeDisplayStates.Bold)) ? Font : BoldFont;
                    var iWidth = ListItemStringWidth(labelFont, ref info);
                    var textAlign = GetLabelTextAlignment(ref tdd);
                    if (RightToLeft == RightToLeft.Yes)
                    {
                        // For purposes of hit test calculations, RTL switches near/far alignment. 
                        textAlign = textAlign == StringAlignment.Far ? StringAlignment.Near : StringAlignment.Far;
                    }
                    if (target == VirtualTreeHitTargets.Uninitialized)
                    {
                        if (textAlign == StringAlignment.Near)
                        {
                            target = (x < iWidth)
                                         ? VirtualTreeHitTargets.OnItemLabel
                                         : VirtualTreeHitTargets.OnItemRight;
                        }
                        else
                        {
                            // add labelShift and xItemStart because they've been subtracted from original x value above.
                            target = (x + labelShift + xItemStart > itemLeft + itemWidth - iWidth)
                                         ? VirtualTreeHitTargets.OnItemLabel
                                         : VirtualTreeHitTargets.OnItemLeft;
                        }
                    }

                    if (populateExtras)
                    {
                        var currentTopIndex = TopIndex;
                        extraInfo.IsTruncated =
                            (rawRow != absIndex && absIndex < currentTopIndex) ||
                            ((rawRow == absIndex) &&
                             (0 == (target & (VirtualTreeHitTargets.OnItemRight | VirtualTreeHitTargets.OnItemLeft))) &&
                             ((xItemStart + labelShift + SystemInformation.Border3DSize.Width + iWidth > itemLeft + itemWidth) ||
                              (labelShift + SystemInformation.Border3DSize.Width < 0)));
                        extraInfo.LabelOffset = labelShift;
                        var top = (rawRow - currentTopIndex) * myItemHeight;
                        extraInfo.ClippedItemRectangle = new Rectangle(
                            xItemStart - scrollShift,
                            top,
                            (extraInfo.IsTruncated || textAlign == StringAlignment.Far)
                                ? itemLeft + itemWidth - xItemStart
                                : labelShift + iWidth,
                            // in right align case, clipped item rectangle will always extend the full width, since text draws from the right.
                            myItemHeight);
                        extraInfo.FullLabelRectangle = new Rectangle(
                            xItemStart + labelShift - scrollShift,
                            top,
                            iWidth,
                            myItemHeight);
                        if (textAlign == StringAlignment.Far)
                        {
                            // account for alignment away from glyph.
                            extraInfo.FullLabelRectangle.X = itemLeft + itemWidth - scrollShift - iWidth;
                        }
                        else if (multiColumn
                                 && HasVerticalGridLines
                                 && (column != 0))
                        {
                            // account for vertical gridlines
                            extraInfo.FullLabelRectangle.X += 1;
                        }
                        extraInfo.LabelFont = labelFont;
                        extraInfo.LabelFormat = StringFormat;
                        extraInfo.LabelFormat.Alignment = GetLabelTextAlignment(ref tdd);
                            // get alignment again, so it's not adjusted for RTL.
                    }
                }
            }
            Debug.Assert(target != VirtualTreeHitTargets.Uninitialized);
            return new VirtualTreeHitInfo(absIndex, column, nativeColumn, rawRow, rawColumn, target | blankTargetBit);

            /*INDEX index;
            int cxState, cxImage;
            int xShift;
            ULONG Level;
            IVsLiteTreeList *ptl;
            ULONG ListIndex;
            WORD iWidth;
            VSTREEDISPLAYDATA tdd;

            xShift = Level * pTree->cxIndent;
            xShift -= pTree->xPos;

            if ((pTree->ci.style & (TVS_HASLINES | TVS_HASBUTTONS)) &&
                (pTree->ci.style &TVS_LINESATROOT))
            {
                // Subtract some more to make up for the pluses at the root
                xShift += pTree->cxIndent;
            }

            x -= xShift;

            //Get image offsets.  Not all items have an image, so
            //we have to check that as well here.
            cxState = 0;
            cxImage = pTree->cxImage;
            tdd.Mask = 0;
            tdd.StateMask = 0;
            if (cxImage) 
            {
                tdd.Mask |= TDM_IMAGE;
                tdd.hImageList = NULL;
            }
            if (pTree->himlState) 
            {
                tdd.Mask |= TDM_STATE;
                tdd.StateMask |= TDS_STATEIMAGEMASK;
                tdd.State = 0; //in case of failure
            }
            if (tdd.Mask) 
            {
                ptl->GetDisplayData(ListIndex, &tdd);
                cxState = TV_StateIndex(tdd.State) ? pTree->cxState : 0;
                if (cxImage && tdd.hImageList == NULL && tdd.Image == (USHORT)(-1)) 
                {
                    cxImage = 0;
                }
            }

            //iWidth adjusted from regular
            //treeview which caches iWidth for an item.
            iWidth = TV_ListItemStringWidth(pTree, ptl, ListIndex);
            if (x <= (int) (cxImage + cxState)) 
            {
                if (x >= 0) 
                {
                    if (pTree->himlState &&  (x < cxState)) 
                    {
                        *wHitCode = TVHT_ONITEMSTATEICON;
                    } 
                    else if (pTree->hImageList && (x < (int) cxImage + cxState)) 
                    {
                        *wHitCode = TVHT_ONITEMICON;
                    } 
                    else 
                    {
                        *wHitCode = TVHT_ONITEMLABEL;
                    }
                } 
                else 
                {
                    if ((x >= -pTree->cxIndent) && (pTree->ci.style & TVS_HASBUTTONS)) 
                    {
                        BOOL expandable = FALSE;
                        pTree->pVsTree->GetExpandableAbsolute(index, &expandable);
                        *wHitCode = expandable ? TVHT_ONITEMBUTTON : TVHT_ONITEMINDENT;
                    }
                    else 
                    {
                        *wHitCode = TVHT_ONITEMINDENT;
                    }
                }
                if (pfIsStringTruncated) 
                {
                    *pfIsStringTruncated = ((xShift + cxImage + cxState + g_cxEdge + iWidth > pTree->cxWnd) ||
                        (xShift + cxImage + cxState + g_cxEdge < 0));
                }
            }
            else 
            {
                if (x <= (int) (iWidth + cxImage + cxState)) 
                {
                    *wHitCode = TVHT_ONITEMLABEL;
                    if (pfIsStringTruncated) 
                    {
                        *pfIsStringTruncated = ((xShift + cxImage + cxState + g_cxEdge + iWidth > pTree->cxWnd) ||
                            (xShift + cxImage + cxState + g_cxEdge < 0));
                    } 
                }
                else 
                {
                    *wHitCode = TVHT_ONITEMRIGHT;
                    if (pfIsStringTruncated) 
                    {
                        *pfIsStringTruncated = false;
                    } 
                }
            }

            if (lprcItem && (*wHitCode & TVHT_ONITEM)) 
            {
                lprcItem->left = xShift;
                lprcItem->right = (pfIsStringTruncated && *pfIsStringTruncated) ? pTree->cxWnd : xShift + cxImage + cxState + iWidth;
                lprcItem->top = (index - pTree->iTop) * pTree->cyItem;
                lprcItem->bottom = lprcItem->top + pTree->cyItem;
                if (pcxShiftToLabel) 
                {
                    *pcxShiftToLabel = (LONG)(cxState + cxImage);
                }
            }

            if (ptl) 
            {
                ptl->Release();
            }
            if (pLevel) 
            {
                *pLevel = Level;
            }
            return (INDEX) index;*/
        }