当用户与DateTimePicker控件交互时会引发什么事件?

问题描述 投票:5回答:4

我是C#的新手,在我的程序中我使用DateTimePicker值更改事件,但我发现当用户单击箭头或以编程方式更改值时也会发生ValueChanged事件,我只想识别用户交互的DateTimePicker(不是通过编程方式更改值时),有没有办法做到这一点?

c# .net winforms datetimepicker
4个回答
5
投票
是,请看MSDN documentation。特别是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     }


9
投票
您可以在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; }


1
投票
您可以从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)的示例,但是您不需要自己设置标志,只需依靠此控件即可。

0
投票
您可以检查DateTimePicker控件的

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); } } }

© www.soinside.com 2019 - 2024. All rights reserved.