创建周期性约会时,如何利用AppointmentStore.ShowEditNewAppointmentAsync()返回的ID获取对应约会实例
解决周期性约会创建后无法通过ID获取的问题
这个问题其实是Windows UWP中AppointmentStore处理周期性约会的常见坑——当你创建周期性约会时,ShowEditNewAppointmentAsync返回的ID确实是主约会的Roaming ID,但因为系统对周期性约会采用「主约会+实例约会」的分层存储逻辑,直接用GetAppointmentAsync或者FindLocalIdsFromRoamingIdAsync可能因为同步延迟或API的特殊处理拿不到结果。
这里有几个可行的解决方案:
方案1:通过时间范围+属性筛选定位主约会
既然直接通过ID获取失败,我们可以通过查询最近创建的约会,并结合周期性属性来定位目标主约会。示例代码如下:
var result = await AppointmentStore.ShowEditNewAppointmentAsync(appointment); if (!string.IsNullOrEmpty(result)) { // 先尝试直接获取 var createdAppointment = await AppointmentStore.GetAppointmentAsync(result); if (createdAppointment == null) { // 设置查询时间范围:覆盖当前时间前后1天,确保包含刚创建的约会 var startDate = DateTimeOffset.Now.AddDays(-1); var endDate = DateTimeOffset.Now.AddDays(1); var options = new FindAppointmentsOptions(); // 只筛选带有Recurrence属性的主约会 options.FilterProperties.Add(nameof(Appointment.Recurrence)); var appointments = await AppointmentStore.FindAppointmentsAsync(startDate, endDate, options); // 可通过标题、创建时间等属性进一步精准匹配你刚创建的约会 var masterAppointment = appointments.FirstOrDefault(a => a.Recurrence != null && a.Subject == appointment.Subject); if (masterAppointment != null) { // 获取该主约会下的所有实例约会 var instanceIds = await AppointmentStore.FindInstanceLocalIdsFromMasterLocalIdAsync(masterAppointment.LocalId); var instances = new List<Appointment>(); foreach (var instanceId in instanceIds) { var instance = await AppointmentStore.GetAppointmentAsync(instanceId); instances.Add(instance); } // masterAppointment 是主约会实例,instances 是所有周期性子约会 } } }
方案2:监听约会存储的变更事件
更可靠的方式是订阅AppointmentStore.AppointmentsChanged事件,当系统完成周期性约会的创建与存储同步后,会触发该事件,此时你可以在回调中查询最新的约会:
// 初始化时订阅事件 AppointmentStore.AppointmentsChanged += OnAppointmentsChanged; // 执行约会创建逻辑 var result = await AppointmentStore.ShowEditNewAppointmentAsync(appointment); // 事件回调方法 private async void OnAppointmentsChanged(AppointmentStore sender, object args) { // 查询最近的周期性约会,逻辑同方案1 var startDate = DateTimeOffset.Now.AddDays(-1); var endDate = DateTimeOffset.Now.AddDays(1); var options = new FindAppointmentsOptions(); options.FilterProperties.Add(nameof(Appointment.Recurrence)); var appointments = await sender.FindAppointmentsAsync(startDate, endDate, options); var targetAppointment = appointments.FirstOrDefault(a => a.Subject == "你创建的约会标题"); if (targetAppointment != null) { // 处理主约会及其实例 } }
关键注意点
- 周期性约会的主约会拥有非空的
Recurrence属性,而实例约会的Recurrence为null,但实例约会的MasterLocalId会指向主约会的Local ID。 - 不要依赖即时调用
GetAppointmentAsync获取周期性约会,系统需要一点时间生成所有实例并完成存储同步。 - 如果知道约会的具体属性(如标题、起始时间),可以在查询时加入这些条件,避免匹配到无关约会。
内容的提问来源于stack exchange,提问作者aveschini
相关产品推荐
相关产品推荐

