DataTemplate 中的绑定在第一次加载视图时不起作用

Binding within DataTemplate does not work on first load of view

我在试图绑定到视图模型中的 属性 的自定义控件上有一个依赖项 属性。该控件位于视图中的 DataTemplate 内(UserControl)。但是,绑定似乎只有在视图加载 之后 更改绑定特性时才起作用。

因此,这是视图 XAML:

中内容的示例
<dxb:BarStaticItem Alignment="Far">
    <dxb:BarStaticItem.ContentTemplate>
        <DataTemplate>
            <controls:AllMaxDateRangeCombo Grid.Row="1"
                                           DateRange="{Binding DataContext.WorkOrderDateRange, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=UserControl}}"
                                           TimeFrameType="Current"
                                           Width="150" />
        </DataTemplate>
    </dxb:BarStaticItem.ContentTemplate>
</dxb:BarStaticItem>

BarStaticItem 是将 "normal" 控件放入工具栏时使用的 DevExpress 控件。我在 AllMaxDateRangeCombo 中定义的绑定在首次加载视图时不起作用。但是在运行时(调试期间),如果要通过在名称末尾添加一个数字来更改 属性 名称,然后立即删除该数字,则绑定将开始工作。

由于缺乏更好的理解,我只能说似乎绑定在第一次加载时 "hooked up" 不正确,或者它在某些部分准备就绪之前尝试。但是当我在运行时进行更改时,突然链接了。

我希望这对有人来说足够有意义,可以帮助我弄清楚这里发生了什么。

P.S.: 使用 Snoop 工具,我可以看到控件的依赖项 属性 DateRange 在我进行运行时更改之前根本没有绑定。然后,绑定出现。因此,无论出于何种原因,我定义的绑定都不会在第一次加载视图时启动。

编辑:在回答问题时,我将解释一些机制。 AllMaxDateRangeCombo 基本上是一个带有 LastMonth、Today、LastWeek 等选项的组合框。进行选择后,日期范围将重新计算并分配给控件的 DateRange 依赖项 属性。因为那是我要绑定的 属性,所以我希望 UI 视图模型的 属性 会随之改变。然后我会回复并更新 UI 数据。但是 属性 值永远不会改变。因此,要么绑定从未真正连接起来,要么它无法以某种方式通知更改。

这最终是由于控件中的值发生了变化。在控件中,此依赖项 属性 被定义为:

public static DependencyProperty DateRangeProperty = DependencyProperty.Register("DateRange", typeof(DateTimeRange), typeof(AllMaxDateRangeCombo), new PropertyMetadata(new DateTimeRange(DateTime.MinValue, DateTime.MaxValue)));
public DateTimeRange DateRange
{
    get => (DateTimeRange)GetValue(DateRangeProperty);
    set => SetValue(DateRangeProperty, value);
}

组合框选择更改后,正在设置该值:

private void RecalculateDates()
{
    DateRange = new DateTimeRange(DateTime.MinValue, DateTime.MaxValue);
}

只要控件的使用不在 DataTemplate 中,这在双向绑定中就可以正常工作。但是一旦它在 DataTemplate 中使用,那么只有这个版本有效:

SetCurrentValue(DateRangeProperty, new DateTimeRange(DateTime.MinValue, DateTime.MaxValue));