C# 绑定TimePicker和CalendarDatePicker UWP时的不同行为

C# 绑定TimePicker和CalendarDatePicker UWP时的不同行为,c#,xaml,uwp,windows-10,windows-10-universal,C#,Xaml,Uwp,Windows 10,Windows 10 Universal,这个问题更像是一个好奇的问题,因为我已经找到了一个解决办法,但我仍然想理解其中的区别。我有一个简单的ContentDialog派生类,它允许分别使用CalendarDatePicker和TimePicker选择两个日期和时间。我已将其日期和时间属性绑定如下: <StackPanel Orientation="Vertical" Grid.Column="0" Grid.Row="0">

这个问题更像是一个好奇的问题,因为我已经找到了一个解决办法,但我仍然想理解其中的区别。我有一个简单的ContentDialog派生类,它允许分别使用CalendarDatePicker和TimePicker选择两个日期和时间。我已将其日期和时间属性绑定如下:

        <StackPanel Orientation="Vertical" Grid.Column="0" Grid.Row="0">
            <TextBlock>From</TextBlock>
            <CalendarDatePicker  Date="{x:Bind DateFromDate, Mode=TwoWay}" />
            <TimePicker Time="{x:Bind DateFromTime, Mode=TwoWay}" />
        </StackPanel>

        <StackPanel Orientation="Vertical" Grid.Column="1" Grid.Row="0">
            <TextBlock>To</TextBlock>
            <CalendarDatePicker  Date="{x:Bind DateToDate, Mode=TwoWay}" />
            <TimePicker Time="{x:Bind DateToTime, Mode=TwoWay}" />
        </StackPanel>
您可能会注意到,在绑定到计时器选择器的TimeSpan属性中,有一个检查属性是否已更改。如果我删除它,并将其保留在DateTimeOffset属性中,则每次设置这些属性时都会引发StackOverflowException。如果你用谷歌搜索,你会遇到这样的问题,比如,一个非常明显的无限递归发生在哪里。如果我调试它,setter确实会一次又一次地被调用,因此我的理论是,在TimePicker的代码背后的某个地方,当它接收到通知时,它不仅会获取属性,还会设置属性。有什么想法吗

这里发生了一个非常明显的无限递归。如果我调试它,setter确实会一次又一次地被调用

我可以复制这个问题,它看起来x:Bind双向模型使绑定循环,我可以肯定它不是设计的。目前有许多解决方法

使用绑定替换x:Bind。

public TimeSpan DateToTime
{
    get => _dateToTime;

    set
    {

        _dateToTime = value;
        OnPropertyChanged();

    }
}
       
<TimePicker Time="{Binding DateToTime, Mode=TwoWay}" />
<TimePicker Time="{x:Bind DateFromTime, Mode=OneWay}" />
public TimeSpan DateToTime
{
get=>\u dateToTime;
设置
{
_dateToTime=值;
OnPropertyChanged();
}
}
将双向修改为单向。

public TimeSpan DateToTime
{
    get => _dateToTime;

    set
    {

        _dateToTime = value;
        OnPropertyChanged();

    }
}
       
<TimePicker Time="{Binding DateToTime, Mode=TwoWay}" />
<TimePicker Time="{x:Bind DateFromTime, Mode=OneWay}" />

最新的一个是您提到的使用条件语句来停止这个循环

请随时使用windows反馈中心应用程序报告此信息。我会继续跟踪这个问题

更新

请注意,NotifyPropertyChanged的文档明确指出,只有在值实际更改时才会触发NotifyPropertyChanged事件。 请注意,如果不遵循文档,则行为是未定义的。因此,当不遵循文档时,您不能假设坏场景中的行为是一致的,因为这两种行为都未定义

下面是关于
INotifyPropertyChanged
的说明

只有当属性的setter在值等于上一个值时不防止触发PropertyChanged时,才会出现此问题。因此,不管行为的不同,它们都是未定义的行为。如果你不遵循文档,你应该期望事情以奇怪的方式破裂,同样是因为行为是未定义的

为什么DatePicker可以在没有值等于前一个值的情况下工作


在某些场景中,未定义的行为可能恰好符合预期,但如果它没有遵循文档,则会有风险,因为它可能会在任何时间点更改而没有任何警告。

否,当我使用TimeSpan属性绑定TimePicker时(如您所见),但我不会执行
if(value!=\u dateFromTime)
设置属性时请检查。您是否介意共享可以复制此问题的完整代码?好的,我知道了,我可以复制您的问题。感谢您的关注。我同意这一定是一个bug,当然更可能是这样,如果Binding做得正确,而x:Bind做得不正确。