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

Xamarin.Forms中DatePicker修改Date属性时无法调用函数问题排查

WPF DatePicker绑定SelectedDate时setter调用函数报错原因

相关代码

视图层DatePicker定义:

<DatePicker MinimumDate="{Binding Today}" Date="{Binding SelectedDate, Mode=TwoWay}"/>

ViewModel层属性实现:

private DateTime selectedDate;
public DateTime SelectedDate
{
    get { return selectedDate; }
    set
    {
        selectedDate = value;             
        OnPropertyChanged(nameof(SelectedDate));
        // 直接调用ExecuteFunction()会触发运行时异常
    }
}

private DateTime today;
public DateTime Today
{
    get { return today; }
    set
    {
        today = value;
        OnPropertyChanged(nameof(Today));
        ExecuteFunction(); // 此处调用可正常执行
    }
}

异常根因

该异常属于WPF依赖属性更新流程的重入冲突:

  • 用户操作DatePicker选择日期时,控件正处于Date依赖属性的内部同步更新周期,双向绑定机制会在这个周期内同步调用ViewModel中SelectedDate的set方法。此时DatePicker的内部状态还未完成本次日期选择的全流程更新。
  • 如果在SelectedDate的setter中直接调用ExecuteFunction(),只要函数内存在触发UI线程同步更新的逻辑——比如修改Today属性(即DatePicker的MinimumDate绑定源)、触发关联UI元素重绘、间接修改SelectedDate本身的值,就会触发WPF属性系统的重入保护,抛出无效操作异常。
  • Today属性的setter调用不会触发该问题,是因为Today的赋值逻辑和DatePicker的Date属性更新流程不在同一个同步调用栈中,不会打断控件本身的日期选择处理流程,因此无重入冲突。

修复方案

将函数调用调度到UI线程异步执行,等当前依赖属性的同步更新流程完全结束后再运行目标逻辑,即可规避重入问题:

private DateTime selectedDate;
public DateTime SelectedDate
{
    get { return selectedDate; }
    set
    {
        selectedDate = value;             
        OnPropertyChanged(nameof(SelectedDate));
        // 异步调度执行,避开当前同步更新栈
        Application.Current.Dispatcher.BeginInvoke(
            new Action(ExecuteFunction), 
            System.Windows.Threading.DispatcherPriority.Background
        );
    }
}

如果使用CommunityToolkit.Mvvm、Prism等MVVM框架,也可以直接使用框架提供的属性变更回调异步触发逻辑,效果一致。


内容的提问来源于stack exchange,提问作者João Fernandes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:12:21