简体   繁体   中英

C# DateTimePicker

I have a WinForm with a DateTimePicker control on it showing a specific date from my SQL database.

When the user clicks it, I have a custom form open to ask if they are sure they want to change the date.

If they click OK they can proceed to change the date using the DateTimePicker and the changes are posted back to my SQL Server database.

If the user clicks Cancel instead, the method exits so no changes are saved to the database.

However, what is annoying me, is even when the user clicks Cancel, the DateTimePicker drop down calendar stays open, which a user may interpret as the action having failed to Cancel. How can I get the DateTimePicker to close an open drop down calendar?

private void datDOA_ValueChanged(object sender, EventArgs e)
    {
        frmConfirmBox frmCB = new frmConfirmBox("Are you sure you want to change the Date of Accident?");
        frmCB.ShowDialog();
        if (frmCB.intButton == 0)
        {                
            return;
        }

        datDOA.Format = DateTimePickerFormat.Long;

        //...Connect to Database...//

        string strCaseNo = txtCaseNo.Text;
        string strConnect = BuildConnectionString();
        SqlConnection linkToDB = new SqlConnection(strConnect);
        linkToDB.Open();

        //...Send User Input to Database...//

        DateTime dateNewDate = datDOA.Value;
        string commandText = "UPDATE tblCases SET DOA = @DOAVal WHERE CaseNo = @CaseNoVal;";
        SqlCommand sqlCom = new SqlCommand(commandText, linkToDB);
        sqlCom.Parameters.Add("@DOAVal", SqlDbType.DateTime);            
        sqlCom.Parameters.Add("@CaseNoVal", SqlDbType.VarChar);
        sqlCom.Parameters["@DOAVal"].Value = dateNewDate;
        sqlCom.Parameters["@CaseNoVal"].Value = strCaseNo;
        sqlCom.ExecuteNonQuery();

        linkToDB.Close();
    }        

You need to keep the old value of the DateTimePicker control to switch it back to. Also, your dialog form is interfering with the closing of the drop down, so you have to give it a chance to close.

Something like this:

public partial class Form1 : Form {
  private DateTime _OldValue;

  public Form1() {
    InitializeComponent();
    _OldValue = dateTimePicker1.Value;
    dateTimePicker1.ValueChanged += new EventHandler(dateTimePicker1_ValueChanged);
  }

  void dateTimePicker1_ValueChanged(object sender, EventArgs e) {
    this.BeginInvoke(new MethodInvoker(delegate { ConfirmDateChange(); }));
  }

  private void ConfirmDateChange() {
    frmConfirmBox frmCB = new frmConfirmBox();
    if (frmCB.ShowDialog() == DialogResult.OK) {
      _OldValue = dateTimePicker1.Value;
      // do your database update here
    } else {
      // temporarily stop firing ValueChanged event while we switch it back:
      dateTimePicker1.ValueChanged -= dateTimePicker1_ValueChanged;
      dateTimePicker1.Value = _OldValue;        
      dateTimePicker1.ValueChanged += dateTimePicker1_ValueChanged;
    }
  }
}

I'm not sure what are your requirements, but perhaps you could subscribe to the DateTimePicker ValueChanged event and after they changed the selected date, you can ask them if they're sure that they want to change the date from X to Y. in case they choose cancel you can always roll back to the previous selected date.

EDIT: Assume the name of your DateTimePicker is dateTimePicker1:

Here is a sample class named DTP which will do just that

     public partial class DTP : Form
     {
        DateTime lastSelectedValue;

        public DTP()
        {
         InitializeComponent();

         lastSelectedValue = dateTimePicker1.Value;
         dateTimePicker1.ValueChanged += new EventHandler(dateTimePicker1_ValueChanged);

         }

    void dateTimePicker1_ValueChanged(object sender, EventArgs e)
    {

        DialogResult di =  MessageBox.Show("Change " + lastSelectedValue.ToString() + " to " + dateTimePicker1.Value.ToString(), "?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question)

        if(di== System.Windows.Forms.DialogResult.OK)
        {
            SetSqlDateTimeValue( dateTimePicker1.Value );
            lastSelectedValue =  dateTimePicker1.Value;
        }
        else
        {
             dateTimePicker1.ValueChanged  -= dateTimePicker1_ValueChanged;
            //Setting back the dtp to the old value
            dateTimePicker1.Value = lastSelectedValue;
            dateTimePicker1.ValueChanged += dateTimePicker1_ValueChanged;
        }
    }


    private void SetSqlDateTimeValue(DateTime dateTime)
    {
        throw new NotImplementedException();
    }



}

Notice that I have declared a DateTime varible named lastSelectedValue in the top. then after the value is being change I'll ask the user if he wishes to proceed, if he dose I do the SQL thing, if he dosen't I will set the Value property of the dateTimePicker1 to the lastSelectedValue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM