You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 18:31:07