简体   繁体   English

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

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

I created a DatagridViewNumericUpDownColumn which is actually a custom control but i got error message when I closed and reopen the form: 我创建了一个DatagridViewNumericUpDownColumn,它实际上是一个自定义控件,但是当我关闭并重新打开表单时,出现错误消息:

Cannot access a disposed object. 无法访问已处置的对象。 Object name: 'NumericUpDown' 对象名称:“ NumericUpDown”

I am writing the following code for 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;
            }
        }

Is there any solution for this problem? 这个问题有什么解决办法吗?

This is happening because these events are still being fired while disposing the form (ie closing the form), so you just need this line: 发生这种情况是因为在处置表单(即关闭表单)时仍会触发这些事件,因此您只需要以下行:

if (paintingNumericUpDown.IsDisposed) { return; }

at the top of the method. 在方法的顶部。 It's a by-product of doing your own drawing. 这是您自己绘制图纸的副产品。

the easiest way to solve it i think is in the catch part don't throw, but do new NumericUpDown() if needed. 我认为最简单的解决方法是在catch部分不要扔,但是如果需要,可以执行new NumericUpDown() other way will be not to dispose NumericUpDown or doing new NumericUpDown() when disposing 另一种方法是在处置时不处置NumericUpDown或执行new NumericUpDown()

I encountered a similar problem when using Microsoft's code from here: https://docs.microsoft.com/en-us/previous-versions/aa730881(v=vs.80) 从此处使用Microsoft的代码时,我遇到了类似的问题: https : //docs.microsoft.com/zh-cn/previous-versions/aa730881(v=vs.80)

I imagine you based your solution of this example and that therefore your constructor has this in it: 我想您基于此示例的解决方案,因此构造函数中包含以下示例:

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

I fixed my problem by recreating the paintedNumericUpDown more often: 我通过更频繁地重新创建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;
        }

I hope that works for you too. 我希望这对您也有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 AutoMapper IValueResolver:无法访问已处理的对象。 对象名称:&#39;IServiceProvider&#39; - AutoMapper IValueResolver: Cannot access a disposed object. Object name: 'IServiceProvider' ObjectDisposedException:无法访问已处置的对象。 对象名称:“调度程序” - ObjectDisposedException: Cannot access a disposed object. Object name: 'Dispatcher' C#&#39;无法访问已处置的对象。 对象名称:“ SslStream”。 - C# 'Cannot access a disposed object. Object name: 'SslStream'.' HangFire“无法访问已处置的对象。对象名称:'SqlDelegatedTransaction'” - HangFire "Cannot access a disposed object. Object name: 'SqlDelegatedTransaction'" 无法访问已处置的对象。 对象名称:&#39;tlsxyz&#39; - Cannot access a disposed object. Object name: 'tlsxyz' 无法访问已处置的对象。\\ r \\ n对象名称:“ ApplicationUserManager” - Cannot access a disposed object.\r\nObject name: 'ApplicationUserManager' 无法访问已处置的对象。 与XPO - Cannot access a disposed object. with XPO 无法访问已处置的对象。 交易 - Cannot access a disposed object. Transaction 我有一个 singleton 表单名称 FCD 无法访问已处理的 object 的问题。 Object 名称:'FCD'。 - I have this problem with a singleton form name FCD Cannot access a disposed object. Object name: 'FCD'.' 无法访问已处置的对象。 对象名称:System.net.Sockets.Socket - Cannot access a disposed object. Object name: System.net.Sockets.Socket
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM