Exposing Dependency Properties

A

Anthony Paul

Hello everyone,

I just ran into the following scenario and couldn't figure out
something that I thought should be easy as pie.

I have a class that contains a dependency property, let's say it's a
DateTime property. I can bind directly to this property via TwoWay and
all is well. Now I want to create a user control that uses this class
within it, but I want to expose this DateTime dependency property sort
of like this :

public class MyUserControl : UserControl
....
public DateTime ExposedDateTimeProperty
{
get
{
return SomeClass.DateTimeProperty;
}
set
{
SomeClass.DateTimeProperty = value;
}
}

but if I try to bind to this (again, TwoWay binding) I get nothing
since ExposedDateTimeProperty is a regular CLR get/setter property and
not a dependency property. So the million dollar question is : How
does one expose a dependency property? I can't seem to find any
documention or example of this anywhere.

Regards,

Anthony
 
A

Anthony Paul

Hello Nicholas,

Thanks for answering. I tried using the Inherits flag and wasn't able
to get it to work. In trying to understand why it wasn't working, I
read somewhere that it will only work if the class is contained within
the visual tree, but this class isn't a visual. All I want to do is
expose the dependency property just like I would a regular CLR
property and be able to bind to it.

Regards,

Anthony
 
N

Nicholas Paldino [.NET/C# MVP]

Anthony,

If that is the case, then I would add a new DependencyProperty for the
exposed property. This DependencyProperty would have a
PropertyChangedCallback delegate assigned to it to handle when the property
changed on your dependency property.

Then, in the callback delegate, I would get the dependency property for
the contained class property you want to change, and then set the property
value.

Finally, you will want to make the get part of your exposed property
dependent on the internal dependency property. Jan-Cornelius Molnar has a
blog entry about how he tracks the value of another dependency property:

http://vb-magazin.de/forums/blogs/janm/archive/2006/05/04/3762.aspx

The combination of these two things should allow you to funnel values
to/from your contained instance.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Hello Nicholas,

Thanks for answering. I tried using the Inherits flag and wasn't able
to get it to work. In trying to understand why it wasn't working, I
read somewhere that it will only work if the class is contained within
the visual tree, but this class isn't a visual. All I want to do is
expose the dependency property just like I would a regular CLR
property and be able to bind to it.

Regards,

Anthony
 
A

Anthony Paul

Thanks Nicholas, I will give that a try when I get home and if it
works I'll post the solution; if not, there will be more lamentations
and gnashing of teeth.

Regards,

Anthony
 
A

Anthony Paul

Hey Nicholas,

The link you sent was an excellent resource and when I read through it
the lightbulb switched on and I thought to myself "Of course, why
didn't I think of that?!"

In the end it turned out to be simpler than what you mentioned in your
email; there's no need to specify a callback at all, the only thing we
need to do is create the same dependency property on the user control
as follows :

public class MyUserControl : UserControl
...
public DateTime ExposedDateTimeValue
{
get
{
return SomeClass.DateTimeValue;
}
set
{
SomeClass.DateTimeValue = value;
}
}


Register it as follows (notice that I use AddOwner method here so as
not to re-create the same type of dependency property; we just want to
re-use it) :

public static readonly DependencyProperty ExposedDateTimeValueProperty
= SomeClass.DateTimeValueProperty.AddOwner(typeof(MyUserControl), new
FrameworkPropertyMetadata(new DateTime?(),
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

and then in the constructor of my user control I do as follows :

Binding binder = new Binding("DateTimeValue");
binder.Source = this;
binder.Mode = BindingMode.TwoWay;
BindingOperations.SetBinding(helper, SomeClass.DateTimeValueProperty,
binder);


So the solution to it all was to create a simple binding between the
two properties... duh! However, I would like to say that there should
be some mechanism built into the CLR that generates this binding
automatically sort of the way it hides the complexity behind
delegates.

Thanks for your assistance Nicholas!

Regards,

Anthony
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top