9

我有一个控件,它公开了一个名为 PlacementTarget 的 DP(它绑定到一个子 Popup FWIW)。

我想要做的是,如果 PlacementTarget 未在 XAML 中设置,那么(控件将)将其设置为控件所在的窗口。当我说“未设置”时,我并不是指简单的“为空”(这允许用户 dev 将 PlacementTarget 设置为 null,并且控件不会自动将其设置为 Window)。

我有一个名为placementTargetIsSet 的字段,我在Change 事件处理程序中将其设置为true

public readonly static DependencyProperty PlacementTargetProperty =
    DependencyProperty.Register(
        "PlacementTarget", typeof(UIElement), typeof(MyControl),
        new PropertyMetadata(new PropertyChangedCallback(PlacementTargetChanged)));

static void PlacementTargetChanged(
    DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    MyControl ctrl = (sender as MyControl);
    ctrl.placementTargetIsSet = true;
}

public UIElement PlacementTarget
{
    get { return (UIElement)GetValue(PlacementTargetProperty); }
    set { SetValue(PlacementTargetProperty, value); }
}

但是我发现更改的事件发生在 OnApplyTemplate 和 Loaded 事件之后。即当 OnApplyTemplate 或 Loaded 发生时,placementTargetIsSet==false,无论 PlacementTarget 是否已设置(在 XAML 中)。

那么我什么时候可以安全地假设 PlacementTarget 尚未设置?

4

1 回答 1

16

您不需要额外的placementTargetIsSet字段,因此不需要 PropertyChangedCallback。

为了确定是否为PlacementTarget属性设置了值,您只需调用ReadLocalValue方法并测试它是否返回DependencyProperty.UnsetValue

bool placementTargetIsSet =
    ReadLocalValue(PlacementTargetProperty) != DependencyProperty.UnsetValue;
于 2013-11-05T20:47:22.080 回答