DateTimePicker期日选择控件.怎么判断用户是否选择过

hiddkiller 2009-11-16 03:07:41
如题.
日期控件弹出选择框再收回后. 怎么知道用户是否有选择?

其中有个问题. 当用户选择了打开选择框之前的日期,这个时候怎么知道用户有选择.
...全文
1397 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
lzsh0622 2009-11-17
  • 打赏
  • 举报
回复
楼主,你测试一下,效果出来了.

[ToolboxBitmap(typeof(System.Windows.Forms.DateTimePicker))]
public partial class DateTimeControl : DateTimePicker
{
bool isChanged; // 新加 在选择窗口内是否选择了其他值
DateTimePickerFormat _format;
string _customFormat;
bool SetValue = false;//表示当前是否是系统在改变Value属性
/// <summary>
/// 获取或设置分配给控件的日期/时间值
/// </summary>
public new DateTime ? Value
{
get
{
if ((base.CustomFormat == null || base.CustomFormat.Trim() == "") && base.Format == DateTimePickerFormat.Custom)
return null;
else return base.Value;
}
set
{
if (value == null) SetNullValueFormat();
else
{
SetDefaultFormat();
SetValue = true;
base.Value = (DateTime)value;
}
}
}


/// <summary>
/// 格式掩码类型
/// </summary>
public new DateTimePickerFormat Format
{
get
{
return base.Format;
}
set
{
base.Format = value;
_format = base.Format;
}
}
/// <summary>
/// 自定义格式
/// </summary>
public new string CustomFormat
{
get
{
return base.CustomFormat;
}
set
{
base.CustomFormat = value;
_customFormat = base.CustomFormat;
}
}
/// <summary>
/// 构造方法
/// </summary>
public DateTimeControl()
{
_format = base.Format;
_customFormat = base.CustomFormat;
}

protected override void OnKeyUp(KeyEventArgs e)
{
if (e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete)
{
Value = null;
base.OnKeyUp(e);
SetNullValueFormat();
}
else
{
base.OnKeyUp(e);
}

}
protected override void OnValueChanged(EventArgs eventargs)
{
base.OnValueChanged(eventargs);
if (!SetValue)//如果当前是系统在改变Value属性,将不执行以下操作
{
DateTime dt = DateTime.Now;
DateTime dt2 = new DateTime(base.Value.Year, base.Value.Month, base.Value.Day, dt.Hour, dt.Minute, dt.Second);
SetValue = true;//设置当前是系统在改变Value属性.
base.Value = dt2;
SetValue = false;//设置系统改变Value属性的过程已经结束.
}
isChanged = true;
}


protected override void OnDropDown(EventArgs eventargs)
{
isChanged = false;
}

/// <summary>
///
/// </summary>
/// <param name="eventargs"></param>
protected override void OnCloseUp(EventArgs eventargs)
{
base.OnCloseUp(eventargs);
if (isChanged) SetDefaultFormat();
}

/// <summary>
/// 设置空值格式
/// </summary>
private void SetNullValueFormat()
{
if (Value == null) return;
SetValue = true; //设置当前是系统在改变Value属性.
_format = base.Format;
_customFormat = base.CustomFormat;
base.Format = DateTimePickerFormat.Custom;
base.CustomFormat = " ";
}
/// <summary>
/// 恢复默认格式
/// </summary>
private void SetDefaultFormat()
{
base.Format = _format;
base.CustomFormat = _customFormat;
}
}


说明:
(1)基本结构沿用你在17楼提供的代码 (感觉方法还可以优化)
(2)新加一字段 isChanged 用于记录在选择窗口内是否通过选择改变了value.
(3)重写一事件 OnDropDown 用于初始化 isChanged = false
(4)在OnCloseUp事件中, if (isChanged) SetDefaultFormat();
lxl930 2009-11-17
  • 打赏
  • 举报
回复
小问题大道理!
suners 2009-11-17
  • 打赏
  • 举报
回复
关注
lzsh0622 2009-11-17
  • 打赏
  • 举报
回复
应该能解决,楼主的思路很好,解决了null问题,正在研究控件重绘事件,不选则中止重绘事件。
hiddkiller 2009-11-17
  • 打赏
  • 举报
回复
哈, 多谢关注.一会加点分. 解不解决都给分的.谢谢大家.
hiddkiller 2009-11-17
  • 打赏
  • 举报
回复
16楼.

如果你试试就知道了. 就17楼的例子.
随便设置一个格式(CustomFormat属性) yyyy-MM-dd

先用键盘删除当前显示的值.好了现在Value为空.在这种情况下.你试试我说的那两种操作. 打开选择框后选择 旧值 以及不选择.
liujb1982 2009-11-17
  • 打赏
  • 举报
回复
up
wartim 2009-11-17
  • 打赏
  • 举报
回复
最好整理下思路,比如这样

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

namespace WindowsApplication154
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();

dateTimePicker1.Format = DateTimePickerFormat.Custom;
dateTimePicker1.CustomFormat = "yyyy-MM-dd HH:mm:ss";
dateTimePicker1.Leave += new EventHandler(dateTimePicker1_Leave);
}

void dateTimePicker1_Leave(object sender, EventArgs e)
{
dateTimePicker1.Value = DateTime.Parse(dateTimePicker1.Value.Date.ToString("yyyy-MM-dd ")
+ DateTime.Now.ToString("HH:mm:ss"));
}
}
}
hiddkiller 2009-11-17
  • 打赏
  • 举报
回复
我14楼的代码是根据7楼给的代码乱写的例子
给吧 看看嘛. 这个才我现在出问题的.
可以选择null的 日期选择控件


[ToolboxBitmap(typeof(System.Windows.Forms.DateTimePicker))]
public partial class DateTimeControl : DateTimePicker
{
DateTimePickerFormat _format;
string _customFormat;
bool SetValue = false;//表示当前是否是系统在改变Value属性
/// <summary>
/// 获取或设置分配给控件的日期/时间值
/// </summary>
public new DateTime? Value
{
get
{
if ((base.CustomFormat == null || base.CustomFormat.Trim() == "") && base.Format == DateTimePickerFormat.Custom)
return null;
else
return base.Value;
}
set
{
if (value == null)
{
SetValueNullToFormat();
}
else
{
FurbishFormat();
SetValue = true;
base.Value = (DateTime)value;
}
}
}


/// <summary>
/// 格式掩码类型
/// </summary>
public new DateTimePickerFormat Format
{
get
{
return base.Format;
}
set
{
base.Format = value;
_format = base.Format;
}
}
/// <summary>
/// 自定义格式
/// </summary>
public new string CustomFormat
{
get
{
return base.CustomFormat;
}
set
{
base.CustomFormat = value;
_customFormat = base.CustomFormat;
}
}
/// <summary>
/// 构造方法
/// </summary>
public DateTimeControl()
{
_format = base.Format;
_customFormat = base.CustomFormat;
}

protected override void OnKeyUp(KeyEventArgs e)
{
if (e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete)
{
Value = null;
}
base.OnKeyUp(e);
}
protected override void OnValueChanged(EventArgs eventargs)
{
base.OnValueChanged(eventargs);
if (!SetValue)//如果当前是系统在改变Value属性,将不执行以下操作
{
DateTime dt = DateTime.Now;
DateTime dt2 = new DateTime(base.Value.Year, base.Value.Month, base.Value.Day, dt.Hour, dt.Minute, dt.Second);
SetValue = true;//设置当前是系统在改变Value属性.
base.Value = dt2;
SetValue = false;//设置系统改变Value属性的过程已经结束.
}
}
/// <summary>
///
/// </summary>
/// <param name="eventargs"></param>
protected override void OnCloseUp(EventArgs eventargs)
{
FurbishFormat();
base.OnCloseUp(eventargs);
}
/// <summary>
/// 设置值为空时的格式
/// </summary>
private void SetValueNullToFormat()
{
if (Value == null)
return;
SetValue = true;//设置当前是系统在改变Value属性.
_format = base.Format;
_customFormat = base.CustomFormat;
base.Format = DateTimePickerFormat.Custom;
base.CustomFormat = " ";
}
/// <summary>
/// 恢复格式
/// </summary>
private void FurbishFormat()
{
base.Format = _format;
base.CustomFormat = _customFormat;
}
}
qldsrx 2009-11-17
  • 打赏
  • 举报
回复
楼主,你似乎没有明白,“点击选择框显示出来之后,根本就没有去选择”是不会触发ValueChanged事件的,另外即使你去选择了,如果不改变值,也不会触发ValueChanged事件的。另外使用该事件还有一个及其危险的问题,就是当你手动用当前系统的时分秒替换掉value的时分秒后,又一次触发ValueChanged事件,又一次执行替换,而每次执行替换时,当前系统的时分秒不会一样的,以致于导致死循环,所以不应该通过ValueChanged事件来实现。

看了下那个控件的事件不怎么多,似乎都不能满足要求,所以你应该重写该控件来实现。一会给你贴一段重写的DateTimePicker类,以实现各种需求。
surlew 2009-11-17
  • 打赏
  • 举报
回复
在_ColseUp事件里面处理,ColseUp事件里面不管是你点击还是只是拉开都可以进这个事件的
hiddkiller 2009-11-17
  • 打赏
  • 举报
回复
lzsh0622谢谢你.
你试试这个能解决不?
以下是设置一个dateTimePicker实例 初始值是2009-11-15.
好了,运行后我要在用户有选择或者有键盘改变日期后, 用当前系统的时分秒替换掉value的时分秒.

键盘改变日期都会触发valueChanged事件.这倒是容易解决.



关键问题是 用户点击选择框显示出来之后.选择了2009-11-15 那怎么处理?
或者点击选择框显示出来之后,根本就没有去选择,而是使dateTimePicker控件失去焦点使之收回选择框呢?我要在第一种情况下替换时分秒,第二种却不做任何处理,现在问题就是这两种情况无法区分.



public Form18()
{
InitializeComponent();
dateTimePicker1.Enter+=new EventHandler(dateTimePicker1_Enter);
dateTimePicker1.ValueChanged+=new EventHandler(dateTimePicker1_ValueChanged);
dateTimePicker1.Value = DateTime.Parse("2009-11-15");

}




DateTime dt;
private void dateTimePicker1_Enter(object sender, EventArgs e)
{
dt = dateTimePicker1.Value;
}

private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
if (dateTimePicker1.Value < dt)
{
MessageBox.Show("以前的日期");
}
dt = dateTimePicker1.Value; // 根据情况可以不改
}




谢谢了.
lzsh0622 2009-11-17
  • 打赏
  • 举报
回复
打错分了,哪是核心代码,呵呵,没关系。
hiddkiller 2009-11-17
  • 打赏
  • 举报
回复
还有 lzsh0622, 呵,

我以为都一个人呢.
hiddkiller 2009-11-17
  • 打赏
  • 举报
回复
哈.! 你把问题绕过去了. 只是把之前的值设置到最小值去.
不过我也想了好久,最多也只能到这个份了. 不然就得继承Control自己另写一个DateTimePicker

好了,谢谢了.. 特别感谢qldsrx
qldsrx 2009-11-17
  • 打赏
  • 举报
回复
各种尝试下来,要做到区分选择框是否选择了才关闭,是做不到的,主要原因是那个选择后通过基类的属性进行的赋值操作,派生类即便重新了Value或者Text属性,也不会触发Set操作。不能从属性Set操作入手就根本无法实现了,仅有的事件是无法区分的,不过我将楼主的代码改了一下,至少可以解决“先用键盘删除当前显示的值.好了现在Value为空.在这种情况下.你试试我说的那两种操作. 打开选择框后选择 旧值 以及不选择. ”的问题。

[ToolboxBitmap(typeof(System.Windows.Forms.DateTimePicker))]
public partial class DateTimeControl : DateTimePicker
{
DateTimePickerFormat _format;
string _customFormat;
bool SetValue = false;//表示当前是否是系统在改变Value属性
bool isnull = false;

/// <summary>
/// 获取或设置分配给控件的日期/时间值
/// </summary>
public new DateTime? Value
{
get
{
if (isnull)
return new DateTime?();
else
return base.Value;

}
set
{
if (value == null)
{
isnull = true;
SetValue = true;
base.Value = base.MinDate;
SetValue = false;
SetValueNullToFormat();

}
else
{
isnull = false;
FurbishFormat();
SetValue = true;
base.Value = (DateTime)value;
SetValue = false;
}
}
}

/// <summary>
/// 格式掩码类型
/// </summary>
public new DateTimePickerFormat Format
{
get
{
return base.Format;
}
set
{
base.Format = value;
_format = base.Format;
}
}
/// <summary>
/// 自定义格式
/// </summary>
public new string CustomFormat
{
get
{
return base.CustomFormat;
}
set
{
base.CustomFormat = value;
_customFormat = base.CustomFormat;
}
}
/// <summary>
/// 构造方法
/// </summary>
public CusDateTimePicker()
{

_format = base.Format;
_customFormat = base.CustomFormat;

}

protected override void OnKeyUp(KeyEventArgs e)
{
if (e.KeyCode == Keys.Back || e.KeyCode == Keys.Delete)
{
Value = null;
}
base.OnKeyUp(e);
}
protected override void OnValueChanged(EventArgs eventargs)
{
if (!SetValue)//如果当前是系统在改变Value属性,将不执行以下操作
{
DateTime dt = base.Value.Date + DateTime.Now.TimeOfDay;
Value = dt;
}
base.OnValueChanged(eventargs);
}


/// <summary>
/// 设置值为空时的格式
/// </summary>
private void SetValueNullToFormat()
{
SetValue = true;//设置当前是系统在改变Value属性.
base.Format = DateTimePickerFormat.Custom;
base.CustomFormat = " ";
SetValue = false;
}
/// <summary>
/// 恢复格式
/// </summary>
private void FurbishFormat()
{
base.Format = _format;
base.CustomFormat = _customFormat;
}
}
qqiuzaihui 2009-11-17
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 lzsh0622 的回复:]
....
[/Quote]
写得这么好,只有帮顶的份了。
lzsh0622 2009-11-16
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 hiddkiller 的回复:]
好像很简单.就是要选择事件,不是要值改变事件.
[/Quote]

我感觉不同,用这个控件的目的是要结果,而不是中间过程按了几个键。

你再想想,7楼的思路已经解决了这个问题了。

(1)用户进来前的原始值:在Enter事件保存起来了。
(2)改变日期值的方法:可以选择、可以直接输入,都会影响一个事件ValueChanged。
(3)在这个事件中,可以处理:
a.新值不符合要求时,要求重新选择。
b.新值不符合要求时,自动恢复原值。
c. ...
如果从选择上考虑就走远路了,那还得考虑按键事件。
hiddkiller 2009-11-16
  • 打赏
  • 举报
回复
winform
lzsh0622 2009-11-16
  • 打赏
  • 举报
回复
楼主问题没说清,是webform 还是winform 方法不一样的.
加载更多回复(10)

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧