2

我创建了一个 DatagridViewNumericUpDownColumn,它实际上是一个自定义控件,但是当我关闭并重新打开表单时出现错误消息:

无法访问已处置的对象。对象名称:'NumericUpDown'

我正在为 numericupdown 编写以下代码

[ThreadStatic]
        private static NumericUpDown paintingNumericUpDown; 

 protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState,
                                      object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle,
                                      DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            try
            {
                if (this.DataGridView == null)
                {
                    return;
                }

                // First paint the borders and background of the cell.
                base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle,
                           paintParts & ~(DataGridViewPaintParts.ErrorIcon | DataGridViewPaintParts.ContentForeground));

                Point ptCurrentCell = this.DataGridView.CurrentCellAddress;
                bool cellCurrent = ptCurrentCell.X == this.ColumnIndex && ptCurrentCell.Y == rowIndex;
                bool cellEdited = cellCurrent && this.DataGridView.EditingControl != null;

                // If the cell is in editing mode, there is nothing else to paint
                if (!cellEdited)
                {
                    if (PartPainted(paintParts, DataGridViewPaintParts.ContentForeground))
                    {
                        // Paint a NumericUpDown control
                        // Take the borders into account
                        Rectangle borderWidths = BorderWidths(advancedBorderStyle);
                        Rectangle valBounds = cellBounds;
                        valBounds.Offset(borderWidths.X, borderWidths.Y);
                        valBounds.Width -= borderWidths.Right;
                        valBounds.Height -= borderWidths.Bottom;
                        // Also take the padding into account
                        if (cellStyle.Padding != Padding.Empty)
                        {
                            if (this.DataGridView.RightToLeft == RightToLeft.Yes)
                            {
                                valBounds.Offset(cellStyle.Padding.Right, cellStyle.Padding.Top);
                            }
                            else
                            {
                                valBounds.Offset(cellStyle.Padding.Left, cellStyle.Padding.Top);
                            }
                            valBounds.Width -= cellStyle.Padding.Horizontal;
                            valBounds.Height -= cellStyle.Padding.Vertical;
                        }
                        // Determine the NumericUpDown control location
                        valBounds = GetAdjustedEditingControlBounds(valBounds, cellStyle);

                        bool cellSelected = (cellState & DataGridViewElementStates.Selected) != 0;

                        if (renderingBitmap.Width < valBounds.Width ||
                            renderingBitmap.Height < valBounds.Height)
                        {
                            // The static bitmap is too small, a bigger one needs to be allocated.
                            renderingBitmap.Dispose();
                            renderingBitmap = new Bitmap(valBounds.Width, valBounds.Height);
                        }
                        // Make sure the NumericUpDown control is parented to a visible control
                        if (paintingNumericUpDown.Parent == null || !paintingNumericUpDown.Parent.Visible)
                        {
                            paintingNumericUpDown.Parent = this.DataGridView;
                        }
                        // Set all the relevant properties
                        paintingNumericUpDown.TextAlign = DataGridViewNumericUpDownCell.TranslateAlignment(cellStyle.Alignment);
                        paintingNumericUpDown.DecimalPlaces = this.DecimalPlaces;
                        paintingNumericUpDown.ThousandsSeparator = this.ThousandsSeparator;
                        paintingNumericUpDown.Font = cellStyle.Font;
                        paintingNumericUpDown.Width = valBounds.Width;
                        paintingNumericUpDown.Height = valBounds.Height;
                        paintingNumericUpDown.RightToLeft = this.DataGridView.RightToLeft;
                        paintingNumericUpDown.Location = new Point(0, -paintingNumericUpDown.Height - 100);
                        paintingNumericUpDown.Text = formattedValue as string;

                        Color backColor;
                        if (PartPainted(paintParts, DataGridViewPaintParts.SelectionBackground) && cellSelected)
                        {
                            backColor = cellStyle.SelectionBackColor;
                        }
                        else
                        {
                            backColor = cellStyle.BackColor;
                        }
                        if (PartPainted(paintParts, DataGridViewPaintParts.Background))
                        {
                            if (backColor.A < 255)
                            {
                                // The NumericUpDown control does not support transparent back colors
                                backColor = Color.FromArgb(255, backColor);
                            }
                            paintingNumericUpDown.BackColor = backColor;
                        }
                        // Finally paint the NumericUpDown control
                        Rectangle srcRect = new Rectangle(0, 0, valBounds.Width, valBounds.Height);
                        if (srcRect.Width > 0 && srcRect.Height > 0)
                        {
                            paintingNumericUpDown.DrawToBitmap(renderingBitmap, srcRect);
                            graphics.DrawImage(renderingBitmap, new Rectangle(valBounds.Location, valBounds.Size),
                                               srcRect, GraphicsUnit.Pixel);
                        }
                    }
                    if (PartPainted(paintParts, DataGridViewPaintParts.ErrorIcon))
                    {
                        // Paint the potential error icon on top of the NumericUpDown control
                        base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText,
                                   cellStyle, advancedBorderStyle, DataGridViewPaintParts.ErrorIcon);
                    }
                }
            }
            catch 
            {
                throw;
            }
        }

这个问题有什么解决办法吗?

4

3 回答 3

1

发生这种情况是因为在处理表单(即关闭表单)时仍然会触发这些事件,因此您只需要这一行:

if (paintingNumericUpDown.IsDisposed) { return; }

在方法的顶部。这是自己画画的副产品。

于 2013-07-01T13:58:44.667 回答
0

我认为解决它的最简单方法是在捕获部分不要扔,但new NumericUpDown()如果需要的话。其他方式是不处置 NumericUpDown 或new NumericUpDown()处置时做

于 2013-07-01T14:34:59.477 回答
0

我从这里使用微软的代码时遇到了类似的问题:https://docs.microsoft.com/en-us/previous-versions/aa730881(v=vs.80)

我想您基于此示例的解决方案,因此您的构造函数中包含以下内容:

        // Create a thread specific NumericUpDown control used for the painting of the non-edited cells
        if (paintingNumericUpDown == null)
        {
            paintingNumericUpDown = new NumericUpDown();
            // Some properties only need to be set once for the lifetime of the control:
            paintingNumericUpDown.BorderStyle = BorderStyle.None;
            paintingNumericUpDown.Maximum = Decimal.MaxValue / 10;
            paintingNumericUpDown.Minimum = Decimal.MinValue / 10;
        }

我通过更频繁地重新创建paintedNumericUpDown 来解决我的问题:

        // Create a thread specific NumericUpDown control used for the painting of the non-edited cells
        if (paintingNumericUpDown == null || paintingNumericUpDown.IsDisposed)
        {
            paintingNumericUpDown = new NumericUpDown();
            // Some properties only need to be set once for the lifetime of the control:
            paintingNumericUpDown.BorderStyle = BorderStyle.None;
            paintingNumericUpDown.Maximum = Decimal.MaxValue / 10;
            paintingNumericUpDown.Minimum = Decimal.MinValue / 10;
        }

我希望这也对你有用。

于 2019-09-06T13:28:02.677 回答