【C#】【Form】DateTimePicker [2] ~ Null値を許容 ~


■ サンプル

class NullableDateTimePicker : System.Windows.Forms.DateTimePicker
{
  #region メンバ変数

  // Nullかどうか
  private bool isNull;

  // Null値の時の画面表示
  private string nullValue;

  // DateTimePickerのFormat
  private DateTimePickerFormat pickerFormat;

  // DateTimePickerのCustomFormat
  private string customFormat;

  // CustomFormatの値
  private string formatAsString;
  #endregion

  #region プロパティ

  public new String CustomFormat
  {
      get
      {
          return this.customFormat;
      }
      set
      {
          this.customFormat = value;
      }
  }

  public new DateTimePickerFormat Format
  {
      get
      {
          return this.pickerFormat;
      }
      set
      {
          this.pickerFormat = value;
          this.SetFormat();
          base.OnFormatChanged(EventArgs.Empty);
      }
  }

  [Browsable(true)]
  [DefaultValue("")]
  [Description("null値の場合のテキスト表示")]
  public String NullValue
  {
      get
      {
          return this.nullValue;
      }
      set
      {
          this.nullValue = value;
      }
  }

  public new Object Value
  {
      get
      {
          if (this.isNull)
          {
              return null;
          }
          return base.Value;
      }
      set
      {
          if (value == null ||
              Convert.IsDBNull(value) ||
              (!string.IsNullOrWhiteSpace(this.nullValue) &&
              this.nullValue == value.ToString()))
          {
              this.SetToNullValue();
          }
          else
          {
              this.SetToDateTimeValue();
              base.Value = (DateTime)value;
          }
      }
  }

  public DateTime DateTimeValue
  {
      get
      {
          return Convert.ToDateTime(this.Value);
      }
  }

  public bool IsNull
  {
      get
      {
          return this.isNull;
      }
  }

  private string FormatAsString
  {
      get
      {
          return this.formatAsString;
      }
      set
      {
          this.formatAsString = value;
          base.CustomFormat = value;
      }
  }
  #endregion

  public NullableDateTimePicker3()
      : base()
  {
      base.Format = DateTimePickerFormat.Custom;
      this.nullValue = null;
      this.Format = DateTimePickerFormat.Long;
  }
  #endregion

  #region メソッド

  protected override void OnCloseUp(EventArgs e)
  {
      if (Control.MouseButtons == MouseButtons.None &&
          this.isNull)
      {
          this.SetToDateTimeValue();
          this.isNull = false;
      }
      base.OnCloseUp(e);
  }

  protected override void OnKeyUp(KeyEventArgs e)
  {
      switch (e.KeyCode)
      {
          case Keys.Delete:
              this.Value = this.nullValue;
              base.OnValueChanged(EventArgs.Empty);
              e.Handled = true;
              break;
      }
      base.OnKeyUp(e);
  }

  protected override void OnKeyPress(KeyPressEventArgs e)
  {
      base.OnKeyPress(e);
      if (this.isNull && Char.IsDigit(e.KeyChar))
      {
          // 数字
          this.Value = base.Value;
          e.Handled = true;
          SendKeys.Send("{RIGHT}");
          SendKeys.Send(e.KeyChar.ToString());
          return;
      }
      else if (e.KeyChar == '\b')
      {
          // backspace key
          this.Value = this.nullValue;
          base.OnValueChanged(EventArgs.Empty);
          e.Handled = true;
      }
      base.OnKeyPress(e);
  }

  // Formatプロパティの設定
  private void SetFormat()
  {
      CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
      DateTimeFormatInfo dateTimeFormat = cultureInfo.DateTimeFormat;
      switch (this.pickerFormat)
      {
          case DateTimePickerFormat.Long:
              this.FormatAsString = dateTimeFormat.LongDatePattern;
              break;
          case DateTimePickerFormat.Short:
              this.FormatAsString = dateTimeFormat.ShortDatePattern;
              break;
          case DateTimePickerFormat.Time:
              this.FormatAsString = dateTimeFormat.ShortTimePattern;
              break;
          case DateTimePickerFormat.Custom:
              this.FormatAsString = this.CustomFormat;
              break;
      }
  }

  // DateTime時の値の設定
  private void SetToDateTimeValue()
  {
      if (this.isNull)
      {
          this.SetFormat();
          this.isNull = false;
          base.OnValueChanged(new EventArgs());
      }
  }

  // null時の値の設定
  private void SetToNullValue()
  {
      this.isNull = true;
      base.CustomFormat = string.IsNullOrEmpty(this.nullValue)
          ? " " : this.nullValue;
  }
  #endregion
}

関連記事

DateTimePicker [1] ~ 基本編 ~

https://blogs.yahoo.co.jp/dk521123/28700738.html