WPF has a lot of great concepts. One of my favorite is data binding. The syntax though can get pretty tough and you end up having to reference some kind of cheat sheet every time you want to use it. Also you can’t bind directly to methods, instead you have to wrap methods around “commands”.
These limitations really slow you down. Luckily WPF binding is extendable, so I created my own binding which simplified things a lot. Below are some examples an a link to download the source code.
Before
{Binding} {Binding Path=PathToProperty, RelativeSource={RelativeSource Self}} {Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}} {Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}} {Binding Path=Text, ElementName=MyTextBox} {Binding Path=MyBoolVar, RelativeSource={RelativeSource Self}, Converter={StaticResource InverseBooleanConverter}} // Opposite of boolean value - aka !MyBoolVar
After
{BindTo} {BindTo PathToProperty} {BindTo Ancestor.typeOfAncestor.PathToProperty} {BindTo Template.PathToProperty} {BindTo #MyTextBox.Text} {Binding !MyBoolVar}
Method Binding: Before
// in your class (RelayCommand available separately) private ICommand _saveCommand; public ICommand SaveCommand { get { if (_saveCommand == null) { _saveCommand = new RelayCommand(x => this.SaveObject()); } return _saveCommand; } } private void SaveObject() { // do something } // in your xaml {Binding Path=SaveCommand}
Method Binding: After
// in your class private void SaveObject() { // do something } // in your xaml {BindTo SaveObject()}
You can download the source code or DLLs for this library using these links:
Source Code WpfBindTo.zip
Just the DLL WpfBindTo.dll
About RelayCommand
The ‘BEFORE’ example for binding to a method is already shorter than it would have been without the aid of RelayCommand
which I don’t believe is a native part of WPF. You can find the code for that here:
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
Let me know what you think in the comments below. If you like what you’ve read sign up for my mailing and get notified of new posts and other goodies.
Anonymous says
You’re link to the source code is broken. Perhaps you could post it on CodeProject or on CodePlex?
Luis Perez says
I just tried it and it worked, can you try it again.
Anonymous says
Your*
DJ Burb says
For some odd reason, it says “The type ‘BindTo’ was no found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.”
But it still works…. I just can’t see my XAML designer anymore
Anonymous says
Luis this is beautiful!!! I just implemented it in a huge wpf project and the bindings are being simplified all the way down!!! Im happy as a dog with two tails!
Luis Perez says
I’m happy your happy Anonymous. Spread the word and maybe one day we can live in a world where bindings don’t have to be complicated.
Salvador Sarpi says
Hey Luis, I write the above comment, BindTo is really impressive!! is there a shortcut for binding to StaticResources?? I have not tested that yet! thanks!!
Luis Perez says
Hey Salvador, thanks again for your comment. I don’t believe I created a binding for static resources, I created this library a long time ago, more than 2 years before I posted it here.
What it does it parse the string sent to it and then create the corresponding equivalent WPF binding. You can extend the code, specifically the portion that parses “Ancestor” or “Template” and add one for “StaticResource”.
But to be honest with you I don’t know what you would gain. The syntax for StaticResource is already pretty concise already “{StaticResource ResourceName}”.
The shortest syntax you could create with BindTo would be {BindTo StaticResource.ResourceName} or maybe just {BindTo Resource.ResourceName}. Unless you wanted to use a symbol like {BindTo $ResourceName}.
Unless there’s an opportunity to simplify more complex variations of StaticResource? But I’m not familiar with any.
I hope that answers your question.
Pravin says
Have you done some performance tests on your binding extensions?
Luis Perez says
I have not performance tested it.
I suspect that my bindings are a little slower on load when the expressions are parsed.
The method binding invocation would technically be slower due to the use of reflection for method invocation. But the difference would not be noticeable in most cases since events don’t fire in “tight” loops.
I created the library mostly for development productivity. I think because it’s easy to write and read maintenance is easier.
Also binding to methods directly is faster and requires less code than binding to commands.
That said it would be interesting to do some performance testing and see how it does.
Any suggestions on how I could performance test it?
Anonymous says
Great thank you Luis for sharing! The ability to bind directly to a class method (and not an ICommand) property solved an important problem for me. I use MVVM and wanted to reuse my ViewModel classes in Mono, which does not support ICommand (in System.Windows.Input). Your creative use of a MarkupExtension allow me to remove the System.Windows.Input dependency from my ViewModel classes so they can be reused in Mono. :)
Ted Wrinch says
Hi Louis,
I love the direct binding to methods feature, which is brilliant! As you say, this simplifies what is otherwise an unnecessarily laborious process. A big thanks,
T.
Luis Perez says
Thanks for taking the time to write that Ted. I’m glad you liked it. Tell your friends :)
Anonymous says
wow!
-iyab
Luis Perez says
Thanks. I’m glad you think so.
Anonymous says
This is very nice! I’d like to use it in a project I’m starting on.
Would you please clarify under what license conditions you have made this available?
Luis Perez says
I hadn’t considered releasing it under a license – I’ll have to give that some thought. Thanks.
Anonymous says
If I may offer some suggestions re license terms:
1) Default license:
By posting the code in the blog entry you did “release it under a license” ;-) – the default license for any (c) work under the law – which is probably not what you intended (or you’d have not posted it to begin with).
By default, you as the author retain all rights, and publishing it in the blog gives readers the ability to read it, but does not give the various rights needed to actually use the code. Readers of the post technically can’t copy it, make derivative works, distribute it etc without your permission. It could be argued that everyone using the code from the blog entry is technically committing a (c) violation.
This “legal default” is why when I see a nifty little piece of code that doesn’t have explicit terms of use, I ask.
(I do like this lib – it’s one of those that had me say “Dang, I why didn’t I think of that?”.
2) Most permission approach:
Just put a notice on the blog post that the code is free to use in any way someone wants.
This grants the most permission; and gives you no protection re warranty issues etc.
3) Permissive license with disclaimer approach:
The problem with #1 is that you get no disclaimer for bugs etc. To cover that and still be permissive (assuming you want folks to use it in the same way they probably have been since the blog post was made), I’d suggest a MIT license – simple, easy to understand, well known, lets the code be used without many restrictions and attaches the warranty disclaimer. ref: http://opensource.org/licenses/MIT
4) Viral requirement licenses:
I’d say stay away from either the GPL or LPGL for this lib. The viral nature of either of those licenses would prevent the use of the code in almost all commercial scenarios. Under viral licenses, linking to the BindTo DLL forces the entire app to become (L)GPL – and that is a show stopper for most of the world’s working programmers (particularly those who are employed by a company). I’m assuming that since you first published the code openly, that you didn’t intend for it to require those side effects.
5) Invent your own license:
As the author of the code, you get to offer it under whatever therms you want to dream up.
However, acceptance of non-common licenses for small libs is problematic. Folks tend to either just say no thanks, or ignore the license terms. I’d not recommend this approach for a small lib.
That’s my free advice (worth every penny you paid for it ) –
Dave
Patrick Szalapski says
Is there a way to bind to the current Binding context, i.e. what standard plain old {Binding} without any parameters does? I can just use {Binding}. of course, but would like to be consistent and use {BindTo} for everything.
Luis Perez says
Just as you can use
{Binding}
to bind to the current context, you can also use{BindTo}
if you want to remain consistent.Tony says
Genius, I’m just about to download it and look at your code, I can’t wait but felt compelled to say thanks first. From the before/after results I can already say good work!
Baloogan says
Thanks so much for making this.
Walse says
Wonderful class!
I just find a relatively important drawback. Would there be any way to raise the CanExecuteChanged event? As it’s written, I am afraid that it will have to use the Enabled property, instead of the CanExecute method.