我是C#的新手,在我的程序中我使用DateTimePicker值更改事件,但我发现当用户单击箭头或以编程方式更改值时也会发生ValueChanged事件,我只想识别用户交互的DateTimePicker(不是通过编程方式更改值时),有没有办法做到这一点?
OnValueChanged
事件您将需要使用此事件来连接控件:
在构造方法中:
dateTimePickerControl.ValueChanged += new EventHandler(picker_ValueChanged);
这是方法签名:
void f_ValueChanged(object sender, EventArgs e) { //Do whatever you need when the value changes here }
您也可以从设计师那里进行。如果转到“属性”,然后单击“事件”部分,它将列出所有事件。只需双击,它将为您创建方法签名和连线。更新为您的更新
如果您特别想检查这是否是程序更改,那么您想做这样的事情:在您的课程中创建全局变量
[
Boolean isProgrammaticEvent = false
;在进行程序更改之前:
]
isProgrammaticEvent = true; //Change picker value
在您进行接线时:]
void f_ValueChanged(object sender, EventArgs e) { Boolean isThisProgrammatic = isProgrammaticEvent; isProgrammaticEvent = false; if(isThisProgrammatic) return; //Do whatever you need when the value changes here }
DropDown
事件上关闭事件处理程序,并在用户在CloseUp
事件中关闭下拉日历时将其重新打开:private void dateTimePicker1_ValueChanged(object sender, EventArgs e) {
this.Text = dateTimePicker1.Value.ToString();
}
private void dateTimePicker1_DropDown(object sender, EventArgs e) {
dateTimePicker1.ValueChanged -= dateTimePicker1_ValueChanged;
}
private void dateTimePicker1_CloseUp(object sender, EventArgs e) {
dateTimePicker1.ValueChanged += dateTimePicker1_ValueChanged;
dateTimePicker1_ValueChanged(sender, e);
}
[这可防止在下拉菜单中用户滚动浏览日历时触发ValueChanged
事件。要以编程方式更改日期而不触发事件,请使用相同的概念:
private void ProgramChangesDateTime(DateTime dt) { dateTimePicker1.ValueChanged -= dateTimePicker1_ValueChanged; dateTimePicker1.Value = dt; dateTimePicker1.ValueChanged += dateTimePicker1_ValueChanged; }
DateTimePicker
派生出来,以了解用户何时进行了更改:class DateTimePickerUser : DateTimePicker
{
private bool userSetValue;
public bool UserSetValue
{
get
{
return userSetValue;
}
}
public DateTimePickerUser()
{
userSetValue = true;
}
public new DateTime Value
{
get
{
return base.Value;
}
set
{
userSetValue = false;
base.Value = value;
userSetValue = true;
}
}
}
[当您在DateTimePickerUser
上使用Form
时,只需检查ValueChanged事件中的标志:
private void dateTimePickerUser1_ValueChanged(object sender, EventArgs e) { if (dateTimePickerUser1.UserSetValue) this.Text = "User changed value."; else this.Text = "Code changed the value."; }
这类似于贾斯汀·皮洪尼(Justin Pihony)的示例,但是您不需要自己设置标志,只需依靠此控件即可。
Focused属性。如果为假,则可能意味着该值已以编程方式更改。此外,您可以检查日历弹出窗口当前是否打开。
唯一的例外是用户在日期时间选择器中输入的情况。public class MyDateTimePicker : DateTimePicker
{
/// <summary>
/// Occurs when the property Value is changed programmatically.
/// </summary>
public event EventHandler<EventArgs> ValueChangedProgrammatically;
/// <summary>
/// Gets or sets a boolean that indicates if the calendar popup is open.
/// </summary>
public bool IsOpen { get; private set; }
/// <summary>
/// Raises the ValueChangedProgrammatically event.
/// </summary>
/// <param name="e">Event arguments.</param>
protected virtual void OnValueChangedProgrammatically(EventArgs e)
{
ValueChangedProgrammatically?.Invoke(this, e);
}
/// <summary>
/// Raises the DropDown event.
/// </summary>
/// <param name="e">Event arguments.</param>
protected override void OnDropDown(EventArgs e)
{
base.OnDropDown(e);
IsOpen = true;
}
protected override void OnCloseUp(EventArgs e)
{
base.OnCloseUp(e);
IsOpen = false;
}
/// <summary>
/// Raises the ValueChanged event.
/// </summary>
/// <param name="e">Event arguments.</param>
protected override void OnValueChanged(EventArgs e)
{
base.OnValueChanged(e);
if (!Focused && !IsOpen)
{
/* If the control has no focus and the calendar is not opened, the value is most likely changed programmatically. */
OnValueChangedProgrammatically(e);
}
}
}