WPF中如何临时禁用事件避免DatePicker重复执行方法?
WPF DatePicker 重复触发事件的解决方案
我开发基于XAML的C# WPF项目时,在窗口中使用DatePicker控件,需要在两个时机执行Do_Something():
- 窗口加载完成时
DatePicker日期变更时
最初的实现代码如下:
public void LoadData() { date_DatePicker.SelectedDate = DateTime.Today; Do_Something(); } private void DatePicker_DateChanged(object sender, SelectionChangedEventArgs e) { if (date_DatePicker.SelectedDate.HasValue) { Do_Something(); } }
但窗口加载时设置SelectedDate会触发DateChanged事件,导致Do_Something()被执行两次。尝试通过e.OriginalSource判断失败,因为此时日期已经被填充。
以下是几种可行的解决方案:
方案一:临时移除/重新绑定事件
在加载数据时先移除DateChanged事件绑定,设置完日期后再重新绑定,避免代码触发事件导致重复执行:
public void LoadData() { // 移除事件绑定 date_DatePicker.SelectedDateChanged -= DatePicker_DateChanged; date_DatePicker.SelectedDate = DateTime.Today; // 重新绑定事件 date_DatePicker.SelectedDateChanged += DatePicker_DateChanged; Do_Something(); } private void DatePicker_DateChanged(object sender, SelectionChangedEventArgs e) { if (date_DatePicker.SelectedDate.HasValue) { Do_Something(); } }
方案二:用标记区分代码触发与用户操作
添加布尔标记,在代码设置日期时标记为“忽略事件”,事件处理时检查该标记:
private bool _isSettingDateProgrammatically; public void LoadData() { _isSettingDateProgrammatically = true; date_DatePicker.SelectedDate = DateTime.Today; _isSettingDateProgrammatically = false; Do_Something(); } private void DatePicker_DateChanged(object sender, SelectionChangedEventArgs e) { // 代码设置日期时直接跳过 if (_isSettingDateProgrammatically) return; if (date_DatePicker.SelectedDate.HasValue) { Do_Something(); } }
方案三:通过事件参数判断前后值
利用SelectionChangedEventArgs的RemovedItems集合获取变更前的值,判断是否为初始加载场景:
private void DatePicker_DateChanged(object sender, SelectionChangedEventArgs e) { // 判断是否是从无值变为有值的初始加载场景 bool isInitialLoad = e.RemovedItems.Count == 0 && date_DatePicker.SelectedDate.HasValue; // 初始加载时跳过,因为LoadData中已执行过一次 if (isInitialLoad) return; if (date_DatePicker.SelectedDate.HasValue) { Do_Something(); } }
注意:此方案需确保DatePicker初始状态下SelectedDate为null,否则需调整判断逻辑。
内容的提问来源于stack exchange,提问作者Dominique
相关产品推荐
相关产品推荐

