Geeks With Blogs

News



Add to Google

Tim Hibbard CEO for EnGraph software

Let's say you have a custom WPF control called SearchTextBox.  It has a textbox and a button labeled "search".  Simple enough, you reuse it in your application when you want to provide search. 

Then one day, you decide you need this control needs to be bindable.  So you expose a public property Text and map it to textSearch just like you would in WinForms.

Well, that doesn't work, so you google around and stumble upon Dependency Properties and learn how to create your own (VS snippet shortcut propdb) and create a Text DP.

Now you spend 30 minutes trying to map your Text DP to your textSearch.Text until you finally figure out that your DP snippet lead you astray and there is one more step that didn't get included in the shortcut.  In the UIPropertyMetaData, you need to specify a function to call when the property changes - so you can set textSearch.Text.

The function looks like this:

static void textChangedCallBack(DependencyObject property, DependencyPropertyChangedEventArgs args) { SearchTextBox searchTextBox = (SearchTextBox)property; searchTextBox.textSearch.Text= (string)args.NewValue; }

And the rest of the DP looks like this:

public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } public static readonly DependencyProperty TextProperty = DependencyProperty.Register( "Text", typeof(string), typeof(SearchTextBox), new UIPropertyMetadata(string.Empty, new PropertyChangedCallback(textChangedCallBack)));

 

The important part here is what wasn't created by the VS snippet :

new UIPropertyMetadata(string.Empty, new PropertyChangedCallback(textChangedCallBack))

Now you are binding to your custom control and all is good.

 

Posted on Tuesday, April 22, 2008 1:11 AM .NET , WPF | Back to top


Comments on this post: WPF Custom Control Dependency Property Gotcha

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Umm, why should you need to do this? The binding should work perfectly well without it.
Left by Dmitri on May 15, 2008 12:38 PM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Actually, it doesn't. I've tried :)
Left by Tim Hibbard on May 15, 2008 12:42 PM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
My example was for people that needed to bind their business objects to a user control, which requires a DP...unless I'm wrong.
Left by Tim Hibbard on May 15, 2008 3:42 PM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Mike's thing works well. The thing I missed was adding a X:Name to the <Window.
Left by Nick on May 20, 2008 1:24 PM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Thanks very much Tim. Took me forever to figure out how to do this!

If want to re-use the callback function you can fetch the argument name like so:

if (args.Property.Name.Equals("Text"))
{
searchTextBox.textSearch.Text= (string)args.NewValue;
}

Left by Lach on Jul 29, 2008 12:38 AM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Thank you Tim!

I spent most of yesterday trying to solve this problem, and looking at your solution it makes sense.. just wish I found your post a bit earlier :-)
Left by Chris on Mar 17, 2009 5:17 AM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
You can't access the property in the constructor. You need to get it in the UserControl_Loaded event.
Left by Alex Kwiatkowski on Mar 20, 2009 2:58 AM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
I've tried all those methods, they work well my Main problem is that its OneWay binding .(ie the textbox in UserControl changes its text when the property in my class changes, but typing in the text box dosen't change the underlaying property.)
This is my 11th day on this, pls i really need help. Thanx alot.
Left by Majeed on Sep 09, 2009 5:47 AM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
wow ... wish i would have found this post yesterday ! i have been abusing google for this for some time. i got mike's sugestion to work for me ... thanks guys. loads of infomation.
Left by John Little on Nov 03, 2009 10:47 AM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Thanks for posting this. Wish I would have found it sooner. It's surprising that something like this is more clearly spelled out in the MSDN docs.
Left by Jake on Dec 10, 2009 12:22 PM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Hi

I have a problem that drives me crazy: I have a usercontrol (UcSelect=textbox+button) which works as expected when used as a "single control" when used this way:
<local:UcSelect Grid.Row="1" x:Name="ucSingle1" UcText="{Binding FirstName, Mode=TwoWay}"/>
When I use it in a datagridcolumn all is fine but the changes I make in the column are not going back in my "FirstName" property.
I think the problem is my "GenerateEditingElement", maybe someone can help me out?
Here is the derived column:
Public Class DerivedColumn
Inherits DataGridTextColumn

Protected Overloads Overrides Function GenerateElement(ByVal oCell As DataGridCell, ByVal oDataItem As Object) As FrameworkElement

Dim oElement = MyBase.GenerateElement(oCell, oDataItem)
Return oElement

End Function

Protected Overloads Overrides Function GenerateEditingElement(ByVal oCell As DataGridCell, ByVal oDataItem As Object) As FrameworkElement

Dim oUc As New UcSelect
Dim oBinding As Binding = CType(Me.Binding, Binding)
oUc.SetBinding(UcSelect.UcTextProperty, oBinding)
Return oUc

End Function

End Class

And here is the Codebehind of my usercontrol:
Private Shared Sub textChangedCallBack(ByVal [property] As DependencyObject, ByVal args As DependencyPropertyChangedEventArgs)
Dim UcSelectBox As UcSelect = DirectCast([property], UcSelect)
UcSelectBox.SetValue(UcTextProperty, args.NewValue)
End Sub

Public Property UcText() As String
Get
Return GetValue(UcTextProperty)
End Get

Set(ByVal value As String)
SetValue(UcTextProperty, value)
End Set
End Property

Public Shared ReadOnly UcTextProperty As DependencyProperty = _
DependencyProperty.Register("UcText", _
GetType(String), GetType(UcSelect), _
New FrameworkPropertyMetadata(String.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, New PropertyChangedCallback(AddressOf textChangedCallBack)))

Public Sub New()

' This call is required by the Windows Form Designer.
InitializeComponent()
grid1.DataContext = Me

End Sub

Left by Klaus Wiesel on Mar 19, 2010 3:48 PM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
This works binding from a parent window to user control, but you cant set the dependecny property in the user control and have that value in the parent window. In fact, if the depenecy value in the user control is set to exactly what is saved in the parents bound dependy then the propertyChangedCallBack wont fire at all... this is especially troubling for bools and giving me a headache
Left by Cyrel on Jul 22, 2010 11:25 PM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
In fact, DP stands for "double penetration" and there are other abbreviations like DPP and DAP that its not worth to explain here.
At same time it's not WPF, it is WTF (Windows Troublemaker Foundation). The next step in app development!!

Anyways, your post was useful for me, I was fighting against that bindable properties on my UserControl and your post was very nice.
Left by Commentor on Sep 01, 2010 3:41 AM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Use the following line of code in SearchTextBox's constructor, then you won't have to use the PropertyChangedCallback.

textSearch.SetBinding(TextProperty, "Text");
Left by Jannes on Sep 28, 2010 3:35 AM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Ignore previous comment.
The SetBinding method does nothing, you must use PropertyChangedCallback.
Left by Jannes on Sep 28, 2010 7:08 AM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
yes you should probably use PropertyChangedCallback
Left by electronic medical records on Jan 05, 2011 11:57 PM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Hey,

you missunderstood the using of the changed-call-back. Try following in your Control:

1. Make a DP with Name "Text" like in first post.
2. Name your userControl with x:Name="MyUserControl"
3. Bind you new Text-Property in your xaml:

<TextBox Text={Binding Path=Text, ElementName=MyUserControl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged"} />

The mode TwoWay garants the refresh in both directions and the UpdateSourceTrigger=PropertyChanged sets the event when the property will be refreshed(the default is set to LostFocus)

In the ChangedCallback you can call you own events, i.E. if you need a event for TextChanged make one and invoke this in the callback.
Left by Khar on Jan 12, 2011 7:51 AM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
I think they should call this post.

The bringer of Silverlight developers back from the brink of insanity.

nuf said
Left by Nigel Stratton on Jan 14, 2011 7:34 PM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Thanks to Khar!
it took me many days how to bind to my dp by XAML, and I was expecting that using the change-call-back should not be the solution.

This was the key I was missing:

2. Name your userControl with x:Name="MyUserControl"

After that I could bind to my dp.
Thanx a lot!

Left by R.LUEBESS on Jan 28, 2011 4:21 PM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
There is another way without proppertyChangedCallback.

Even this is probably very easy once you know it, but this "simple" issue also took me several days to find out how exactly it works. So I would like to share another way without proppertyChangedCallback-methode:

1. Make a DP with Name "Text" like in first post (without the textChangedCallBack.)
2. set a DataContext in your UserControll DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"

<UserControl x:Class="SearchTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
...
DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"
...
>


3. Bind you new Text-Property in your xaml:
<TextBox Text={Binding Path=Text, Mode=TwoWay, updateSourceTrigger=PropertyChanged"} />

Make sure to set the DataContext within the UserControl directly, not within another control later. Because you want "Self" to ref to the UserControl.

Maybe this simple thing can help some beginners to get to the next level... (and avoid from missunderstanding the PorpertyChangedCallback)

BR,
Rolf
Left by R.LUEBESS on Feb 01, 2011 4:11 AM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Hi i am very new to WPF. Tried your example, my textChangedCallBack wouldn't fire, I had to add textchanged event on textSearch in usercontrol, and in it Setvalue to dp Textproperty, then it worked.

Am I missing something:(
Left by Vk123 on Feb 09, 2011 3:12 PM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Thanks very much ; I've been beating my head over getting a DP to work properly in a usercontrol until I saw your tip. Works great!
Left by An Nonny Mouse on Mar 21, 2011 1:07 PM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Thank you, life saver!
Left by Andrei on Mar 31, 2011 4:56 PM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Thank you very much
Left by free gift cards on Apr 26, 2011 2:15 PM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
Thanks never thought there would be an easier way to get things like this done.
Left by medical transcription services on Jul 05, 2011 10:19 AM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
THANKS !!!
Left by sergey on Jan 19, 2012 12:47 PM

# re: WPF Custom Control Dependency Property Gotcha
Requesting Gravatar...
I love you man.
Left by Sam on Jan 19, 2012 5:41 PM

Your comment:
 (will show your gravatar)


Copyright © Tim Hibbard | Powered by: GeeksWithBlogs.net | Join free