10

I have a control, which exposes a DP called PlacementTarget (it's bound to a child Popup FWIW).

What I want to do is if PlacementTarget is not set in XAML, then (the control will) set it to the Window the control is in. When I say 'not set' I don't mean simply 'is null' (this allows the user dev to set PlacementTarget to null, and the control won't auto set it to the Window).

I have a field called placementTargetIsSet, which I set to true in the Change event handler

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); }
}

However I'm finding that the changed event is happening AFTER OnApplyTemplate and the Loaded event. i.e. when OnApplyTemplate or Loaded happen, placementTargetIsSet==false, regardless of whether PlacementTarget been set or not (in XAML).

So when can I safely assume that PlacementTarget has not been set?

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
Jim W
  • 4,866
  • 1
  • 27
  • 43

1 Answers1

16

You don't need an extra placementTargetIsSet field and hence no PropertyChangedCallback.

In order to find out if a value has been set for the PlacementTarget property, you could just call the ReadLocalValue method and test if it returns DependencyProperty.UnsetValue:

bool placementTargetIsSet =
    ReadLocalValue(PlacementTargetProperty) != DependencyProperty.UnsetValue;
Clemens
  • 123,504
  • 12
  • 155
  • 268
  • I'm late, but I can't thank you enough for this answer. It just solved a problem I had for a year or so with a helper class that sets properties for all elements in a grid. – Kilazur Oct 27 '16 at 10:05
  • Wow... worked in WPF for several years off and on. Never knew this method existed. – TyCobb Mar 10 '17 at 22:46
  • Is **not working** if you have a Control with a custom style. All of my Properties are `Unset`, even those who have a binding.. – Dominic Jonas Apr 19 '18 at 09:34
  • @DominicJonas It's not supposed to work with values from Style Setters, as those are no **local** values. – Clemens Apr 19 '18 at 09:54
  • 1
    @Clemens Ah then I have missunterstood sth. Is it also possible to know if it is set in `xaml`? Otherwise I have to choose the workaround with the propChanged and the bool flag. – Dominic Jonas Apr 19 '18 at 09:56
  • @Dominic Whether it's XAML or not doesn't matter. It just has to be a local value, e.g. set directly (in code or XAML) or by a Binding. See here: https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/dependency-property-value-precedence#dependency-property-setting-precedence-list – Clemens Apr 19 '18 at 10:23