English 中文(简体)
不得接触被处置的物体“蒙特利尔”
原标题:Cannot access a disposed object "MonthCalendar"

我有这部法典,以月度控制的形式制定和展示。

private void showcalendar_Click(object sender, EventArgs e)
{
    ShowCalendar();
}

void ShowCalendar()
{
    DateTime current5 = DateTime.Now.AddDays(-5);

    MonthCalendar cal = new MonthCalendar();
    Panel panel = new Panel();
    Form f = new Form();

    cal.MaxSelectionCount = 1;
    cal.SetDate(current5);
    cal.DateSelected += new DateRangeEventHandler(DateSelected);
    cal.ShowToday = true;
    panel.Width = cal.Width;
    panel.Height = cal.Height;
    panel.BorderStyle = BorderStyle.FixedSingle;
    panel.Controls.Add(cal);
    f.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
    f.ShowInTaskbar = false;
    f.Size = panel.Size;
    f.Location = MousePosition;
    f.StartPosition = FormStartPosition.Manual;
    f.Controls.Add(panel);
    f.Deactivate += delegate { f.Close(); };
    f.Show();
}

void DateSelected(object sender, DateRangeEventArgs e)
{
    MonthCalendar cal = (MonthCalendar)sender;
    Form f = cal.FindForm();
    f.Close();
}

当我援引Sakalendar月度假控制时,我可以选择自己的日期。 问题是,当我点击某一地区时(目前描述的最低面积) I m 成为例外——“不能进入被处置物体”。 反对名称:Palendar .I.没有知道这一例外是如何产生,如何消除。 你们是否有任何想法?

我的申请不是多面的,只是简单的形式,它援引显示语气功能。

问题回答

一个令人感兴趣的问题:我能找到的唯一办法就是将人口表作为主要形式的财产,而不是使用Hide()。

public partial class Form1 : Form
    {
        Form f = new Form();

        public Form1()
        {
            InitializeComponent();
        }

        private void showcalendar_Click(object sender, EventArgs e)
        {
            ShowCalendar();
        }

        void ShowCalendar()
        {
            DateTime current5 = DateTime.Now.AddDays(-5);

            MonthCalendar cal = new MonthCalendar();
            Panel panel = new Panel();

            cal.MaxSelectionCount = 1;
            cal.SetDate(current5);
            cal.DateSelected += new DateRangeEventHandler(DateSelected);
            cal.ShowToday = true;
            panel.Width = cal.Width;
            panel.Height = cal.Height;
            panel.BorderStyle = BorderStyle.FixedSingle;
            panel.Controls.Add(cal);
            f.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            f.ShowInTaskbar = false;
            f.Size = panel.Size;
            f.Location = MousePosition;
            f.StartPosition = FormStartPosition.Manual;
            f.Controls.Add(panel);
            f.Deactivate += delegate { f.Hide(); };
            f.Show();
        }

        void DateSelected(object sender, DateRangeEventArgs e)
        {
            DateTime selection = e.Start;
            Console.WriteLine("Selected: {0}", selection.ToLongDateString());

            this.Activate(); // Forces popup to de-activate
        }

    }

Workaround to this: remove MonthCalendar from it s parent before closing the form that hosts this MonthsCalendar. So the change is to add line cal.Parent.Controls.Remove(cal). The DateSelected method becomes:

void DateSelected(object sender, DateRangeEventArgs e)
{
    MonthCalendar cal = (MonthCalendar)sender;
    Form f = cal.FindForm();
    cal.Parent.Controls.Remove(cal);
    f.Close();
}

我在3个步骤中迅速找到解决办法。

目标和增强:

  • Rectangle dynamic size fixed under different versions of windows.
  • Validate if principal form is topmost.
  • Unload calendar form from memory without bug.
  • Good behavior between MonthCalendar and MaskedTextBox controls

步骤:

(1) 创建新的窗口申请表,以表格1看待代码,并以以下方式取代所有案文:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private System.Windows.Forms.CheckBox chkShowWeeksNumbers;
        private System.Windows.Forms.CheckBox chkThisFormTopMost;
        private System.Windows.Forms.MaskedTextBox maskedInputBox;
        private System.Windows.Forms.Button btnShowFloatingCalendar;

        public Form1()
        {
            this.chkShowWeeksNumbers = new System.Windows.Forms.CheckBox();
            this.chkThisFormTopMost = new System.Windows.Forms.CheckBox();
            this.maskedInputBox = new System.Windows.Forms.MaskedTextBox();
            this.btnShowFloatingCalendar = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // chkShowNumbersOfWeeks
            // 
            this.chkShowWeeksNumbers.AutoSize = true;
            this.chkShowWeeksNumbers.Location = new System.Drawing.Point(18, 116);
            this.chkShowWeeksNumbers.Name = "chkShowWeeksNumbers";
            this.chkShowWeeksNumbers.Size = new System.Drawing.Size(137, 17);
            this.chkShowWeeksNumbers.TabIndex = 1;
            this.chkShowWeeksNumbers.Text = "Show number of weeks";
            this.chkShowWeeksNumbers.UseVisualStyleBackColor = true;
            // 
            // chkThisFormTopMost
            // 
            this.chkThisFormTopMost.AutoSize = true;
            this.chkThisFormTopMost.Location = new System.Drawing.Point(18, 139);
            this.chkThisFormTopMost.Name = "chkThisFormTopMost";
            this.chkThisFormTopMost.Size = new System.Drawing.Size(124, 17);
            this.chkThisFormTopMost.TabIndex = 2;
            this.chkThisFormTopMost.Text = "This form TopMost";
            this.chkThisFormTopMost.UseVisualStyleBackColor = true;
            this.chkThisFormTopMost.CheckedChanged += new EventHandler(chkThisFormTopMost_CheckedChanged);
            // 
            // maskedInputBox
            // 
            this.maskedInputBox.Location = new System.Drawing.Point(18, 53);
            this.maskedInputBox.Mask = "00/00/0000 00:00";
            this.maskedInputBox.Name = "maskedInputBox";
            this.maskedInputBox.Size = new System.Drawing.Size(115, 20);
            this.maskedInputBox.TabIndex = 3;
            this.maskedInputBox.ValidatingType = typeof(System.DateTime);
            // 
            // btnShowFloatingCalendar
            // 
            this.btnShowFloatingCalendar.Location = new System.Drawing.Point(139, 49);
            this.btnShowFloatingCalendar.Name = "btnShowFloatingCalendar";
            this.btnShowFloatingCalendar.Size = new System.Drawing.Size(65, 27);
            this.btnShowFloatingCalendar.TabIndex = 4;
            this.btnShowFloatingCalendar.Text = "Calendar";
            this.btnShowFloatingCalendar.UseVisualStyleBackColor = true;
            this.btnShowFloatingCalendar.Click += new EventHandler(btnShowFloatingCalendar_Click);

            // 
            // Form1
            // 
            this.Controls.Add(this.btnShowFloatingCalendar);
            this.Controls.Add(this.maskedInputBox);
            this.Controls.Add(this.chkThisFormTopMost);
            this.Controls.Add(this.chkShowWeeksNumbers);

            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //DateTime format using in United States
            //More info: http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo%28v=vs.71%29.aspx
            //           http://msdn.microsoft.com/en-us/library/5hh873ya.aspx

            Thread.CurrentThread.CurrentCulture = new CultureInfo(0x0409);

            CultureInfo cultureInfoUSA = new CultureInfo(0x0409, false);
            this.maskedInputBox.Culture = cultureInfoUSA;
        }

        //Constructor
        clsMonthCalendarBehavior userCalendar = new clsMonthCalendarBehavior();

        private void btnShowFloatingCalendar_Click(object sender, EventArgs e)
        {           
            userCalendar.ShowCalendar(this.maskedInputBox,
                                      this.chkShowWeeksNumbers.Checked,
                                      this.chkThisFormTopMost.Checked);
        }

        private void chkThisFormTopMost_CheckedChanged(object sender, EventArgs e)
        {
            this.TopMost = this.chkThisFormTopMost.Checked;
        }
    }
}

(2) 在项目中添加新的类别项目,并命名为<编码>clsMonthCalendarBehavior.cs,随后将所有案文改为:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace WindowsFormsApplication1
{
    class clsMonthCalendarBehavior
    {
        private bool manualDateTimeIsDone
        {
            get
            {
                return (SetDateTimeManual(this._dateTimeInput.Text));
            }
        }

        private static DateTime dateTimeManual;

        //Determine if the user inserting a correctly date and time
        internal static bool SetDateTimeManual(string inputReference)
        {
            DateTime newDateTime = new DateTime(2000, 1, 1, 0, 0, 0);

            bool isDateTime = DateTime.TryParse(inputReference, out newDateTime);

            if (isDateTime)
                dateTimeManual = newDateTime;

            return (isDateTime ? true : false);
        }

        private MaskedTextBox _dateTimeInput;

        internal void ShowCalendar(MaskedTextBox dateTimeInput,
                                   bool showNumbersOfWeeks,
                                   bool principalFormIsTopMost)
        {
            MonthCalendar monthCalendarCustomized = new MonthCalendar();
            Panel popupPanel = new Panel();
            Form floatingForm = new Form();

            this._dateTimeInput = dateTimeInput;

            //OPTIONAL: Show week numbers
            monthCalendarCustomized.ShowWeekNumbers = showNumbersOfWeeks;
            monthCalendarCustomized.MaxSelectionCount = 1;

            if (manualDateTimeIsDone)
                monthCalendarCustomized.SetDate(dateTimeManual); //User, date and time selected
            else
                monthCalendarCustomized.SetDate(DateTime.Now); //System, actual date and time

            monthCalendarCustomized.DateSelected += new DateRangeEventHandler(DateSelected);
            monthCalendarCustomized.KeyDown +=new KeyEventHandler(KeyDown);

            monthCalendarCustomized.ShowToday = true;

            //IDEA: bolded dates about references, etc.
            monthCalendarCustomized.BoldedDates = new DateTime[]
            {
                DateTime.Today.AddDays(1),
                DateTime.Today.AddDays(2),
                DateTime.Today.AddDays(7),
                DateTime.Today.AddDays(31),
                DateTime.Today.AddDays(10)
            };

            popupPanel.BorderStyle = BorderStyle.FixedSingle;

            popupPanel.Controls.Add(monthCalendarCustomized);

            floatingForm.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            floatingForm.ShowInTaskbar = false;

            floatingForm.Location = Control.MousePosition;
            floatingForm.StartPosition = FormStartPosition.Manual;

            floatingForm.Controls.Add(popupPanel);
            floatingForm.Deactivate += delegate { floatingForm.Close(); };

            //NOTE: if principal from is topmost, cannot show in front "floatingForm" with calendar 
            //      this option  fix the situation.
            floatingForm.TopMost = principalFormIsTopMost;

            //NOTE: set initial size of controls.
            floatingForm.Size = popupPanel.Size = new Size(20, 20);

            floatingForm.Show();

            popupPanel.Size = floatingForm.Size = monthCalendarCustomized.Size;

            popupPanel.Width = popupPanel.Width + 2;
            popupPanel.Height = popupPanel.Height + 2;

            floatingForm.Width = floatingForm.Width + 3;
            floatingForm.Height = floatingForm.Height + 3;
        }

        void DateSelected(object sender, DateRangeEventArgs e)
        {
            //Set data selected with culture info mask
            this._dateTimeInput.Text = SetTimeValue(e.Start).ToString("MM/dd/yyyy HH:mm");

            CloseFloatingForm(sender);
        }

        private static void CloseFloatingForm(object sender)
        {
            MonthCalendar monthCalendarCustomized = (MonthCalendar)sender;
            Form floatingForm = monthCalendarCustomized.FindForm();

            monthCalendarCustomized.Parent.Controls.Remove(monthCalendarCustomized);

            floatingForm.Close();
        }

        private DateTime SetTimeValue(DateTime selectedDateTime)
        {
            //Recovery time of after selection, because when user select a new date
            //Month Calendar reset the time
            if (manualDateTimeIsDone)
            {
                TimeSpan addTimeValue = new TimeSpan(dateTimeManual.Hour,
                                                     dateTimeManual.Minute,
                                                     dateTimeManual.Second);

                selectedDateTime = selectedDateTime.Add(addTimeValue);
            }

            return (selectedDateTime);
        }

        private void KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
                CloseFloatingForm(sender);                
        }
    }
}

3) 运行和测试。

我认为,问题在于你结束本月日历所载形式,从而处置了你的控制权。

利息。 在此,我可以转录这种罚款(在2008年实行,目标3.5)。 法典中有许多噪音,下面是造成同一行为的原因,即:

  • Selecting any date by clicking on the day/number works
  • Selecting the "today" area at the bottom results in the ObjectDisposedException

降低/降低完成试验:

using System;
using System.Windows.Forms;

namespace Test
{
    public class Form1 : Form
    {
        public Form1()
        {
            var dateSelectionButton = new Button();
            SuspendLayout();
            dateSelectionButton.Text = "Pick Date";
            dateSelectionButton.Click += (SelectDateClick);
            Controls.Add(dateSelectionButton);
            ResumeLayout();
        }

        private void SelectDateClick(object sender, EventArgs e)
        {
            MonthCalendar cal = new MonthCalendar();
            Form f = new Form();
            cal.DateSelected += DateSelected;
            f.Controls.Add(cal);
            f.Show();
        }

        void DateSelected(object sender, DateRangeEventArgs e)
        {
            MonthCalendar cal = (MonthCalendar)sender;
            Form f = cal.FindForm();
            f.Close();
        }
    }
}




相关问题
Bring window to foreground after Mutex fails

I was wondering if someone can tell me what would be the best way to bring my application to the foreground if a mutex was not able to be created for a new instance. E.g.: Application X is running ...

How to start WinForm app minimized to tray?

I ve successfully created an app that minimizes to the tray using a NotifyIcon. When the form is manually closed it is successfully hidden from the desktop, taskbar, and alt-tab. The problem occurs ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

Handle DataTable.DataRow cell change event

I have a DataTable that has several DataColumns and DataRow. Now i would like to handle an event when cell of this DataRow is changed. How to do this in c#?

Apparent Memory Leak in DataGridView

How do you force a DataGridView to release its reference to a bound DataSet? We have a rather large dataset being displayed in a DataGridView and noticed that resources were not being freed after the ...

ALT Key Shortcuts Hidden

I am using VS2008 and creating forms. By default, the underscore of the character in a textbox when using an ampersand is not shown when I run the application. ex. "&Goto Here" is not ...

WPF-XAML window in Winforms Application

I have a Winforms application coded in VS C# 2008 and want to insert a WPF window into the window pane of Winforms application. Could you explain me how this is done.

热门标签