我有一个DevExpress SchedulerControl,它的SchedulerStorage中有各种约会。在某些情况下,由于在应用程序的另一个窗口或另一个实例中所做的更改,约会可能会变得无效。当约会被拖动&放在日历窗口中,我想检测这个&删除约会。
以下是我现在拥有的代码的简化版本:
private void myScheduleControl_AppointmentDrop(object sender, AppointmentDragEventArgs e)
{
if (!IsAppointmentValid(e.EditedAppointment))
{
// remove appointment here
e.Handled = true;
return;
}
// do other stuff
}
问题是,当一个无效的约会被删除时,该代码会运行,但该约会仍然显示在日历中。在调用mySchedulerControl.SuspendLayout()
和mySchedulerControl.ResumeLayout()
之间,我尝试了mySchedulerControl.DeleteAppoint(e.EditedAppointment)
和mySchedulerStorage.Appointments.Remove(e.EditedAppointment)
,但都没有成功。
我使用DevExpress的经验是,如果在处理对象上的事件时调用更改或删除该对象的方法,则该方法通常不会产生任何效果。如何在不重新填充整个ScheduleStorage的情况下删除此约会?
在其他地方,我看到了一个建议,即使用BeginInvoke()
在活动结束后运行。我以前从来没有调用过;如果这是一个有效的方法,我会怎么做?
根据DevExpress的支持,它或多或少是这样做的:
if (!IsAppointmentValid(e.EditedAppointment))
{
BeginInvoke(new Action<SchedulerControl, Appointment>(
delegate(SchedulerControl schdCtrl, Appointment appt)
{
schdCtrl.Storage.Appointments.Remove(appt);
}), mySchedulerControl, e.SourceAppointment);
e.Handled = true;
return;
}
使用e.SourceAppointment
而不是e.EditedAppointment
非常重要,因为e.EditedAppointment
是包含更改的约会的克隆,而e.SourceAppointment
是将要更改的实际约会。删除e.EditedAppointment
无效,因为它不在约会集合中。
在BeginInvoke()
调用中也有必要这样做。在完成事件处理程序之后,执行一些额外的处理,以查找正在拖动的约会&已在约会集合中删除。该集合将在事件期间忽略删除它的请求(即使您正确地要求它删除e.SourceAppointment
),如果您直接更改约会数据源,则在事件处理程序返回后,DevExpress代码中会出现未处理的异常。