2

I have the following code. The PropertyChanged event is being called but the getter and setter is not. I can't for the life of me see why not. I have other properties where the same thing is happening but the values are being set. This is a custom control, if that makes a difference. When I put a breakpoint at the get/set I get nothing. However, the propertychanged is returning the correct value. Any help is greatly appreciated.

    /// <summary>
    /// Identifies the PlacementTarget dependency property.
    /// </summary>
    public static readonly DependencyProperty PlacementTargetProperty =
        DependencyProperty.RegisterAttached(
            "PlacementTarget",
            typeof(UIElement),
            typeof(FunctionPanel),
            new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits, PlacementTargetPropertyChanged)
        );

    /// <summary>
    /// Gets or setsthe PlacementTarget of tooltips for all child controls.
    /// </summary>
    public UIElement PlacementTarget
    {
        get { return (UIElement)GetValue(PlacementTargetProperty); }
        set { SetValue(PlacementTargetProperty, value); }
    }

    /// <summary>
    /// Sets the value of the PlacementTarget dependency property.
    /// </summary>
    /// <param name="target">Target object.</param>
    /// <param name="value">Value argument.</param>
    public static void SetPlacementTarget(DependencyObject target, UIElement value)
    {
        target.SetValue(PlacementTargetProperty, value);
    }

    /// <summary>
    /// Gets the value of the PlacementTarget dependency property.
    /// </summary>
    /// <param name="target">Target object.</param>
    public static UIElement GetPlacementTarget(DependencyObject target)
    {
        return (UIElement)target.GetValue(PlacementTargetProperty);
    }

    /// <summary>
    /// This method is called when the PlacementTarget dependency property changes value.
    /// </summary>
    /// <param name="sender">Sender object.</param>
    /// <param name="e">Event arguments.</param>
    private static void PlacementTargetPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        ToolTipService.SetPlacementTarget(sender, (UIElement)e.NewValue);
    }

Additional Info

So essentially PlacementTargetPropertyChanged is handling it fine. I guess the issue is that this particular DP isn't actually propagating to the children. Here's the XAML snippet:

<controls:FunctionPanel BetweenShowDelay="0"
                        InitialShowDelay="500"
                        IsError="False"
                        Message="MESSAGE"
                        Placement="Right"
                        PlacementTarget="{Binding RelativeSource={RelativeSource Self}}"
                        ShowDuration="60000" />

All of the DPs except PlacementTarget are getting to the children elements. I've tried removing the binding but it made no difference.

I'm verifying the other DPs by using Snoop to check the values. I have created a InitialShowDelay DP that is of type Int. When I set the value to 5000, all child controls inherit that and tooltips delay 5 seconds before appearing. I can verify that the binding is sending the correct control by putting a breakpoint on my PlacementTargetPropertyChanged method.

Update 1

So it seems that PlacementTarget is working fine. The default value of my Placement attached property, which is set to "right", is being ignored. When I set this through XAML, it still doesn't work. However, if I set the value to Top, Left, or Bottom, the tooltips appear in the correct place.

Community
  • 1
  • 1
MCRXB
  • 109
  • 2
  • 7
  • When posting quite some code-updates just edit and post it in your own question. – Viv May 23 '13 at 22:22
  • Yes, I am purposely defining this as an attached property. There are no binding statements on child controls. Because I'm setting FrameworkPropertyMetadataOptions.Inherits, it should flow down to the children. My other attached properties work no problem, just this one. – MCRXB May 24 '13 at 10:51
  • Ah fair enough. I missed the metadata info. So if this exact same code works for other properties, just taking a wild guess here, have ya tried changing the type of the property from UIElement to say FrameworkElement? – Viv May 24 '13 at 11:09
  • Tried and no luck. If I set the relative binding on the child control it works no problem. I'm stumped. – MCRXB May 24 '13 at 11:15

3 Answers3

7

XAML will invoke the SetValue and GetValue methods directly, which is why you shouldn't place any logic in your static Set/Get methods, but use a property changed handler instead.

devdigital
  • 34,151
  • 9
  • 98
  • 120
7

The Setter and Getter are only the .NET Wrappers for your coding. When Binding from XAML the GetXXXX and SetXXX will be called and not the Property Getter and Setter.

You can also access the DependencyProperty PropertyChanged Callback, this function will be called everytime the Property is changed.

Johannes Wanzek
  • 2,825
  • 2
  • 29
  • 47
-1

I've found the reason why the getters and setters didn't appear to be firing. In my placement dependency property, I was setting the default value to PlacementMode.Right. WPF is ignoring the default value. I was then setting it to Placement="Right" in the XAML. Because this value was the same as the default, it was again ignored. By changing the default value to PlacementMode.Relative, I can now successfully set the value to "Right" in the XAML. This does prevent me from using Relative if I want, but I guess that could be solved by converting my properties to an object, which would then have a default of null.

MCRXB
  • 109
  • 2
  • 7
  • This is not really the answer to your question. You asked why the getter/setter wrappers were not being called. That is due to what the other two answers stated. – Alan May 24 '13 at 14:18