DependencyProperty not working in derived UserControl

9775
10
05-18-2010 06:17 AM
RyanCoodey
Regular Contributor
So I have been using DependencyProperties on TemplatedControls and had no issues... I am now making a UserControl that is derived from a TemplateControl...  The class "Toolbar" is a TemplatedControl and is the base for other toolbars.  The class "DataToolbar" is a UserControl derived from "Toolbar", it adds some specific content to the base toolbar and adds a DependencyProperty for a Map control...

For the life of me I cannot get the Map property to be anything other than null, it is not binding... any ideas would be great!  Thanks... Heres a code snippet:

CodeBehind:
public partial class DataToolbar : Toolbar
{
        //Members - Dependency Properties
        protected static readonly DependencyProperty dependencyPropertyMap = DependencyProperty.Register("Map", typeof(Map), typeof(DataToolbar), null);

        //Properties
        public Map Map
        {
            get { return (Map)GetValue(dependencyPropertyMap); }
            set { SetValue(dependencyPropertyMap, value); }
        }
}


XAML:
<local:DataToolbar x:Name="DataToolbar" Map="{Binding ElementName=MyMap}" />


Thanks a lot!!!
0 Kudos
10 Replies
dotMorten_esri
Esri Notable Contributor
You need to follow the guidelines for naming and defining dependency properties. The name and accessibility is important.
Change:
protected static readonly DependencyProperty dependencyPropertyMap ...
to (important changes highlighted):
public static readonly DependencyProperty MapProperty ...

In other words, the DP must be public and must share the name with the property postfixed with "Property". If it isn't, the binding will not be able to find or access the DP.
0 Kudos
RyanCoodey
Regular Contributor
Hmm, I changed to this:

public static readonly DependencyProperty MapProperty = DependencyProperty.Register("Map", typeof(Map), typeof(DataToolbar), null);

and still the Map is null...

Thanks a lot so far Morten!
0 Kudos
DominiqueBroux
Esri Frequent Contributor
A Question just in case:

Isn't your DataToolbar collapsed?
0 Kudos
RyanCoodey
Regular Contributor
Isn't your DataToolbar collapsed?


Nope, its not collapsed.  Nothing in the hierarchy of controls in the usercontrol is collapsed either...  great idea though, thanks!
0 Kudos
RyanCoodey
Regular Contributor
Oh, another thing... putting a break point in the "set" for the property... it never even hits it! 

Is it something to do with it being derived from a TemplateControl maybe?

        public Map Map
        {
            get { return (Map)GetValue(MapProperty); }
            set { SetValue(MapProperty, value); }
        }


*EDIT* Also, FYI, I moved the Dependency Property to the base class (TemplateControl) and it doesnt work there either... and also the base class is derived from ContentControl if that matters at all... THANKS!
0 Kudos
AnilDhiman
New Contributor
I don't exactly what's the reason, but it happens in my case as well. I have a window panel inside which I have kept one usercontrol with dependency property. If I set window panel visibility to collapsed , DP doesn't fire and it works when it is visible.. This looks like a bug in window panel may be it is getting inherited from something which doesn't support DP.
0 Kudos
DominiqueBroux
Esri Frequent Contributor
Hi Ryan,

The SL framework is not using the CLR accessor, so it's normal that your break points in get/set are never used.

What you could test is to define a callback on the property changed and try to put a break point at this level.
Something like:
        //Members - Dependency Properties
        protected static readonly DependencyProperty dependencyPropertyMap = DependencyProperty.Register("Map", typeof(Map), typeof(DataToolbar), new PropertyMetadata(null, OnMapChanged));

 private static void OnMapChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
 { // put a break point here

 }

        //Properties
        public Map Map
        {
            get { return (Map)GetValue(dependencyPropertyMap); }
            set { SetValue(dependencyPropertyMap, value); }
        }

Hopefully this will help.
0 Kudos
RyanCoodey
Regular Contributor
dbroux, thanks a lot for that clarification on the SL framework... I added this callback "OnMapChanged" as you showed and it doesnt appear to ever go in there either 😞
0 Kudos
dotMorten_esri
Esri Notable Contributor
Oh, another thing... putting a break point in the "set" for the property... it never even hits it!


When binding a DependencyProperty will never hit the setter. That's why you have the OnMyPropertyChanged handler. In other words your setter should never have anything but the SetValue(MyProperty, value) in it, and for that very reason any logic you need to execute in a setter should happen in the changed handler.

Are you sure your binding expression is correct and supported? (note that there are limitations as to when and what you can bind to and from - especially when it comes to ElementBinding)
0 Kudos