簡體   English   中英

無法訪問已處置的對象。 對象名稱:“ NumericUpDown”

[英]Cannot access a disposed object. Object name: 'NumericUpDown'

我創建了一個DatagridViewNumericUpDownColumn,它實際上是一個自定義控件,但是當我關閉並重新打開表單時,出現錯誤消息:

無法訪問已處置的對象。 對象名稱:“ NumericUpDown”

我正在為numericalupdown編寫以下代碼

[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;
            }
        }

這個問題有什么解決辦法嗎?

發生這種情況是因為在處置表單(即關閉表單)時仍會觸發這些事件,因此您只需要以下行:

if (paintingNumericUpDown.IsDisposed) { return; }

在方法的頂部。 這是您自己繪制圖紙的副產品。

我認為最簡單的解決方法是在catch部分不要扔,但是如果需要,可以執行new NumericUpDown() 另一種方法是在處置時不處置NumericUpDown或執行new NumericUpDown()

從此處使用Microsoft的代碼時,我遇到了類似的問題: https : //docs.microsoft.com/zh-cn/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;
        }

我希望這對您也有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM