Xamarin.Forms中动态创建的DatePicker值变更时如何获取选中日期?
解决方案
首先修正代码中的明显错误:你给fDate绑定事件时误写为sDate.PropertyChanged += fDate_changed;,正确写法是fDate.PropertyChanged += fDate_changed;,否则结束日期控件的变化不会触发对应的处理方法。
下面提供两种可行的实现方式:
方式一:通过sender参数获取触发事件的DatePicker
事件处理方法中的sender就是触发事件的DatePicker实例,将其转换为DatePicker类型后就能直接获取选中日期。如果需要关联对应的开始/结束日期控件,可以通过StyleId查找配对控件:
if (field.Type == "Timesheets"){ DatePicker sDate = new DatePicker(); sDate.StyleId = field.Name; sDate.PropertyChanged += sDate_changed; DatePicker fDate = new DatePicker(); fDate.StyleId = field.Name; // 修正事件绑定错误 fDate.PropertyChanged += fDate_changed; // 记得将控件添加到容器中(比如面板、布局控件) YourContainerControl.Children.Add(sDate); YourContainerControl.Children.Add(fDate); } private async void sDate_changed(object sender, PropertyChangedEventArgs e) { // 仅处理Date属性变化的事件 if (e.PropertyName == nameof(DatePicker.Date)) { var startDatePicker = sender as DatePicker; if (startDatePicker != null) { // 获取选中的开始日期 DateTime selectedStartDate = startDatePicker.Date; // 根据StyleId查找对应的结束日期控件 var endDatePicker = YourContainerControl.Children.OfType<DatePicker>() .FirstOrDefault(dp => dp.StyleId == startDatePicker.StyleId && dp != startDatePicker); if (endDatePicker != null) { // 可获取对应结束日期或做关联处理 DateTime selectedEndDate = endDatePicker.Date; } } } } private async void fDate_changed(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(DatePicker.Date)) { var endDatePicker = sender as DatePicker; if (endDatePicker != null) { DateTime selectedEndDate = endDatePicker.Date; // 同理查找对应的开始日期控件 var startDatePicker = YourContainerControl.Children.OfType<DatePicker>() .FirstOrDefault(dp => dp.StyleId == endDatePicker.StyleId && dp != endDatePicker); if (startDatePicker != null) { DateTime selectedStartDate = startDatePicker.Date; } } } }
方式二:利用闭包直接捕获控件实例
在创建DatePicker时,使用匿名委托作为事件处理方法,直接捕获当前的sDate和fDate实例,无需额外查找:
if (field.Type == "Timesheets"){ DatePicker sDate = new DatePicker(); sDate.StyleId = field.Name; DatePicker fDate = new DatePicker(); fDate.StyleId = field.Name; // 开始日期变化事件,直接捕获两个控件 sDate.PropertyChanged += async (sender, e) => { if (e.PropertyName == nameof(DatePicker.Date)) { DateTime selectedStart = sDate.Date; DateTime currentEnd = fDate.Date; // 在此直接使用两个日期处理逻辑 } }; // 结束日期变化事件 fDate.PropertyChanged += async (sender, e) => { if (e.PropertyName == nameof(DatePicker.Date)) { DateTime currentStart = sDate.Date; DateTime selectedEnd = fDate.Date; // 处理逻辑 } }; YourContainerControl.Children.Add(sDate); YourContainerControl.Children.Add(fDate); }
两种方式对比
- 方式一适合动态控件数量较多、需要统一管理事件逻辑的场景,能避免闭包可能带来的内存泄漏风险(若控件频繁销毁重建)。
- 方式二更简洁直观、代码量少,适合控件配对逻辑简单的场景。
内容的提问来源于stack exchange,提问作者Mah
相关产品推荐
相关产品推荐

