I've been learning WPF for a few months now and I'm curious about one thing. How does a Binding actually work? I mean, what happends, under the hood. I don't expect that anyone here would give a detailed explanation but maybe a good resource or link where to read up on something like this. I've been searching and googling for this but no good hits so far.
I realize that to fully understand this you would probably have to understand most parts of the framework but a little basic understanding would be great.
Thanks
There are two aspects to consider in binding, getting values in to the UI and having the UI be notified of changes in its DataContext.
Basically you can bind almost anything to any POCO object, the object does not need to implement anything special. The restriction with plain objects is the binding target will not be told when the underlying value changes.
Property changes are propogated through one of three mechanisims:
Dependancy Properties : will notify the binding system when its value changes, can also be used for animations.
INotifyPropertyChanged : If the binding is to a property on an object which implements INotifyPropertyChanged, the binding system will look for subscribe to the PropertyChanged event and update the binding target, when this event is raised, property names are sent as Strings.
*Property*Changed events : The last thing bindings will look for is an event with a name the same as the source property and Changed on the end, so a Name property would need to have a public event called NameChanged, this allows WPF to bind to older .net classes such as 1.1.
I don't know much about the specifics of binding in WPF, but if it's the same principle behind binding in System.ComponentModel and Windows Forms, then a blog article I wrote recently might help to shed some light on it for you:
Some Background on Windows Forms Data Binding
Basically, binding sources have to implement IList, IListSource, ITypedList or IBindingList. Through either reflection or explicit definition, data sources expose PropertyDescriptor objects which describe their bindable properties. The names of these properties (which may or may not be the names of actual properties on the objects contained in the data source - e.g. in DataTable, they are column names instead) are matched against the DisplayMember/ValueMember property or, in the case of WPF, the binding path.
This is quite a difficult question to answer. I believe there are roughly two aspects to an answer. The first is the documentation. If you go through all the documentation of binding expressions, including how paths are build and e.g. the helper classes like BindingOperations, you can find out a lot. If that's not enough, you can always dive into the code by downloading it from the Microsoft Source Initiative site.
Related
I've frequently used WPF to bind a datagrid to a collection of IEditableObject's. Almost every time I do this, it becomes something that I soon regret. Is there an unspoken rule to avoid implementing IEditableObject in my viewmodels altogether?
The most recent problem I've noticed is a memory leak. Some critical internal components (DataBindEngine, CommitManager, BindingGroup) are coordinating together to root memory references. It seems to be happening if the user closes out of a data entry window at an unexpected moment (eg. after a BeginEdit if the user never did anything to trigger a call to "CancelEdit" or "CommitEdit"). The rooting happens in a place that is quite deeply hidden within the databinding engine and it seems extremely difficult to control the default behavior at that level (aside from ensuring that I don't implement IEditableObject in any of my viewmodels).
Unfortunately it isn't always easy to avoid IEditableObject implementations. For example, when binding to ADO.Net, the datagrid wants to use a BindingListCollectionView (for the collection) and the DataRowView class for the individual records. Since the DataRowView class implements IEditableObject, there does not seem to be any way to easily forego the related bugs. I wish there was a way to tell the WPF datagrid to ignore implementations of IEditableObject, and pretend that it wasn't implemented.
On a general basis I'd like to know whether we should avoid binding to IEditableObject (and by that rule we would also avoid binding directly to ADO.Net as well). There seem to be a number of pitfalls to doing so, and I've heard WPF developers who are disparaging of ADO.Net. But I've never seen any formal or authoritative guidance from Microsoft on this matter.
PS. Aside from memory leaks in my databindings, here are some other examples of the types of troubles you can run into when binding to IEditableObject.
Unexpected problems with late binding updates
https://social.msdn.microsoft.com/Forums/vstudio/en-US/d48ccbca-6a3c-4aea-9875-4862fc4a49b9/wpf-datagrid-validate-cell-when-leave?forum=wpf
IEditableObject conflicts with BindingGroup (both attempt to serve
similar purposes)
https://social.msdn.microsoft.com/Forums/vstudio/en-US/7f7196b8-b9dc-487d-93cd-e77f5b3d9906/confused-about-transactional-editing-edititemcanceledit?forum=wpf
IEditableObject protocol problems (because of overlapping goals
with the BindingGroup class)
WPF DataGrid calls BeginEdit on an IEditableObject two times?
Potential fixes (uservoice idea):
Ideally the WPF datagrid would have a property that would allow us to disable all the specialized handling of IEditableObject. This would allow the datagrid to work in a consistent way, whether a viewmodel implemented that interface or not. I found this user voice idea about making the BindingGroup functionality "optional" in a datagrid. I suppose this could have been part of the solution, but the idea was rejected.
https://wpdev.uservoice.com/forums/427690-windows-presentation-foundation-wpf/suggestions/6736492-make-internal-use-of-bindinggroup-in-datagrid-opti
I am new to WPF having previously worked with WinForms on occasion and I still trying to get my head around the WPF mentality, which given my background is embedded coding, seems quite removed.
In my project I need to create a Grid Panel "template", which I'll call "Fred" (where in this case Fred is simply a cluster of graphically customized buttons) and spawn multiple instances of this to the UI programmatically based on external events. I am finding it hard to see an obvious way to do this (perhaps that is because there maybe multiple ways?) and have looked into ControlTemplates, Styles and Custom Elements. I suspect the solution lies in the latter but I am also concerned I might be thinking about this in the wrong way. To me it seems to make sense to visualize Fred as a Grid resource that I can programmatically invoke somehow when I need to create a new instance, but given I found it hard to "google" this very thing then perhaps I am going about this all wrong?
I apologies if this is a bit vague.
My question here is two fold:
Is this a sensible way to achieve my end goal i.e. if I need to programmatically spawn this cluster of customized Buttons (Fred) then does it make sense to contain these in a Grid that can be accessed by the main C# or is there a more standard way that I am missing to achieve this?
Depending on the answer to (1) are there code examples to achieve this?
The concept you are looking for is an "ItemsControl" (which is itself a usable class, and also has several derived classes like ListView and ListBox) in combination with DataTemplates.
In this case you would make "Fred" a DataTemplate (commonly as the direct descendant of your ItemControls ItemTemplate property in XAML). You then bind ItemsSource to a collection (should be ObservableCollection<T> for runtime additions/deletions).
All of this relies on using the MVVM pattern (which coming from WinForms you probably aren't). I would suggest looking at MSDN, Stack Overflow, an excellent blog series by Reed Copsey: http://reedcopsey.com/series/windows-forms-to-mvvm/ or just google "WPF and MVVM" to learn more.
To answer your questions explicitly:
Yes; you have the right concept but are thinking about it in WinForms terms/practices. Use MVVM instead.
Yes; there are many resources available.
I've never used INotifyPropertyChanged, and I'm considering using it widely throughout a new application.
My question is, is it 'proper' to use INotifyPropertyChanged interface in order to provide event notifications for things other than databound controls?
It seems from a bunch of examples online that this interface is widely used for notifying grids and such for when data is changed. I have various scenario's where I need other classes to be notified of data changes in other classes, and I was wondering if you think it's cleaner to implement this interface, and perform the changed call on setters, or rather just create regular events.
When making a choice like this, I lean towards using language features over other constructs.
A severe downside to INotifyPropertyChanged is that it only provides the property name as a string on update, and your consuming classes have to parse that string and decide how to act on it.
With events you can provide any kind of delegate signature that the event requires and the consuming classes can act on that change directly.
If you peek under the hood, you'll find that INotifyPropertyChanged is an event anyway, so why not use events directly?
I think you can use this Interface for those scenarios but you have to really think hard about if you want this thight coupeling between your classes.
If this makes sense to you - sure, why reinvent the wheel?
I think you should go ahead an implement the INotifyPropertyChanged interface, just because it's there for that purpose and its what the UI uses to pickup changes, there's no need to create custom events yourself.
WPF and Silverlight both use INotifyPropertyChanged extensively in the data binding system. If your are going to databind to your objects, you should definetely use INotifyPropertyChanged. |
Otherwise, as far as I know, it does not influence .NET Framework technologies.
INotifyPropertyChanged is not the cleanest way of notifying when your property changes, depending on how you look at it, since there is one event and a string with the propertyname, you will have to make a switch statement. It sure is easier to implement comparing to events per property though
I would not use INotifyPropertyChanged for anything except databinding. This interface is probably the only option for databinding because controls which will act on PropertyChanged event do not know sender's type in advance. Because of that databinding has to use such a generic interface.
For my own types and scenarios I would use regular events (one event per each property which can change its value). INotifyPropertyChanged in such scenarios is kind of stringly typed code. You can see that even WPF itself is still full of oldscool events (FrameworkElement for example with a lot of ***Changed events).
Dont use is in other scenarios, if you need to notify other domain classes use domain events instead, which would be more business oriented and descriptive and strongly typed
I am not a fan of INPC outside of the UI realms as it hides the fact that significant events are being generated by instances of the object. Also, if I use your class implementing INPC, I will expect all properties to broadcast notifications, if only some of them do, that's a bug at runtime that can go unnoticed.
I understand the way wpf supports automatic updates of DataGrids and Listboxes (ie adding new items and removing removed ones) is with the INotifyCollectionChanged interface that ObservableCollection implements. For some reason however I seem to be having complete success binding to an EntityCollection<T> from EntityFramework, which does not seem to implement INotifyCollectionChanged. Is there some other way WPF is doing this?
I'd just like to know how this is working.
EDIT
Here's the relevant portion from the answer. The short form is that it "just works" with WPF and WinForms bindings.
EntityCollection currently does not
implement INotifyCollectionChanged,
which is the “new” standard interface
for notifying collection changes.
However, the binding list that you can
obtain for EntityCollection (and
which databinding will typically get
when you pass and EntityCollection
as a data source) is an IBindingList
which has its own “old” standard way
of notifying of collection changes
(namely, the ListChanged event). In
general, WinForms and WPF databinding
knows how to deal with this interface.
Apparently there was a bug filed on this, but it was closed as "by design" (atleast not for .NET 4).
As this post explains, EntityCollection effectively uses the "old" or WinForms way of list change notification, which uses IBindingList. While WPF uses the "new" INotifyCollectionChanged interface.
This blog post explains a good way to wrap an EntityCollection with a custom ListCollectionView, which you can assign to the ItemsSource property.
You might have a look at the EntityObservableCollection which can be found in the BookLibrary sample application of the WPF Application Framework (WAF). This one ensures that the WPF Binding recognizes all updates.
In C#:
I have a data class that is shared amongst several gui classes. I would like all of the gui classes that use it to be notified when some of the properties change, so they can keep the GUI up to date.
In a couple of the properties I have added delegates that the GUI classes can listen to for updates. This seems to work ok.
The problem I have is that more and more of the properties will require GUI notification. When that happens I will have to add more delegates. It also seems that this is adding an extra responsibility to the data class that it has to manage.
Is there some common pattern that I can use to monitor this class to extract this notification responsibility from the data class?
The common way of doing this is for the data class to implement INotifyPropertyChanged.
EDIT: If you have a lot of properties, this can lead to very repetitive code in the data class, and if you are binding to a UI, it might be best to use an AOP approach and intercept calls to the properties that you want to notify on. Most IoC containers have support for this sort of thing.
The pattern is called Observer. In .Net, events are one implementation of that pattern.
For the specific case of observing individual properties, the INotifyPropertyChanged interface should be used (as #Lee describes).
You don't say what GUI framework (WinForms, WPF) you are using, but there is the INotifyPropertyChanged interface. There is an How to guide on MSDN too.
You can just use the built-in System.EventHandler. That is a pretty standard pattern. You still need to define an event for each property that you want to monitor, but you don't need a separate delegate.
In Windows Forms there are several ways to notify GUI when some properties are chaged using Data Binding.
There are several types of Data binding in Windows Forms.
For simple data binding (data source with one object boud to one control) you can use INotifyPropertyChanged, or you can add events in this format: PropertyNameChanged for every property that you want update in GUI. And you should set Binding.ControlUpdateMode property to OnPropertyChanged.
For complex data binding (data source with many objects bound to control that can display many objects) you should use all from (1) and you should use BindingSource or BindingList or manually implement IBindingList;
For more information you should see this great books:
Windows Forms 2.0 Programming by Chris Sells
Data Binding with Windows Forms 2.0: Programming Smart Client Data Applications with .NET by Brian Noyes