I am in the process of learning WPF, and am puzzled by the fact that databinding exceptions do not cause a runtime/unhandled exception.
Can anyone explain the benefits of databinding working in this way? I'm assuming that there are benefits, but so far I don't see any (disclaimer: I am just getting started with databinding).
Links to resources that explain the theoretical (or practical) reasons for making this decision would work as well.
I don't know for sure, but I suspect it's because there's nowhere to handle the exception.
Suppose you have something whose properties you want to bind to, but sometimes that something is null. (For example, {Binding Name.Length}, where Name is a string property that might be null.) In this case you're happy for this to be a no-op, because you know the control will never be shown when the Name is null (due to a trigger say) or because you know this will be a transient condition while the binding source is loading its data.
Now suppose WPF propagated the NullReferenceException when trying to call Length on the null Name string. In procedural code, you'd catch this exception and swallow it because you knew it was benign. But you don't get to put an exception handler around the WPF binding code. It's called from somewhere deep inside WPF. So the exception would bubble all the way up to Application.Run, which is not a very useful place to catch it.
So rather than making you centralise your binding exception handlers all the way up in Application.Run, I think the WPF guys decided to swallow the exceptions themselves. Only a theory though...
I would argue it is because the cost of producing an Exception is prohibitive. The current implementation works even in the case there are some invalid bindings and in current form that can actually have a very significant effect on performance. Take this example, create a DataGrid that does binding and this load 1,000 records into it. Measure performance with all bindings correct and again with one of them wrong. The difference is considerable. Add on top of that standing up exception class instances and it could get out of control bad. Just my opinion.
I don't know why that is the default behavior, but there are ways around.
For example, even though it will not tell you about the binding error, the Output window will. You can kind of catch that using binding validations as well.
EDIT:
I found this article that has a very good idea to create test cases that will catch those annoying silent binding errors (and I loved the photo at the top of the article)
Here is link to a blog post where the blogger writes about a case where it argues that it does make sense that the binding errors are silent
Related
The WPF designer has a tough job to do. In order to show you a life view of your screen or component it has to execute code but, since you do not control the designer, it has to do this without producing any side effects.
So how does it do that? What are the rules around execution?
What if the view's code-behind code does logging to a file or a service?
What if the code-behind calls MessageBox.Show?
What if the code-behind doesn't have an empty default constructor?
I've hit situations before where I had a default constructor that was checking GetIsInDesignMode and creating and assigning a DataContext if false, and still the designer wasn't rendering correctly. Is there some sort of stack-depth limit?
What are the limitations?
it has to do this without producing any side effects
No, the designer is not that smart. If IsDesignTimeCreatable is specified, it will execute all code in a public parameterless constructor and in properties accessed by bindings. Specifically, it will popup message boxes, write to files, etc -- or throw exceptions trying (just try it yourself).
If you don't have a public parameterless constructor, it can't create an instance, so no code will run.
Regarding your question about "stack depth limit", I know of no such limitation. If you have a specific case where it's not working, I suggest you ask a specific question about that case.
In most cases where the designer fails it is because of an exception or other non-data-related problems (such as missing design-time resources). You should definitely guard code you don't want called during design-time using DesignerProperties.GetIsInDesignMode (I usually add a property IsInDesignMode to the base view model).
This is not exactly answering your question, but to be honest 'how does it work' is not a very specific question.
However rather than dropping this check in to your code-behind, are you aware that you can add something like this to your Xaml?
d:DataContext="{Binding Source={d:DesignInstance Type=namespace:className, IsDesignTimeCreatable=True}}"
This means that you can make a design-time version of your class, e.g. CalculatorDesign :
ICalculator, reference that in the Xaml, and each time you change and compile the design-time class the view will update within VS without running any code or having complicated logic in code-behind.
I’ve been having issues with the TreeView in WPF. This control makes it very hard to access the TreeViewItems it’s showing.
On several occasions I have worked around the need to access a TreeViewItem, for example I’ve accepted the fact that I’m not supposed to access a node’s parent via TreeView (and am supposed to instead keep track of the parent myself). I’ve been doing this for two reasons: first, it’s obviously extremely hard to get at the TreeViewItems, and secondly, I’ve been told that it’s hard because I’m not supposed to need them if I do things right.
However, this time I really see no way around this.
Basically, all I want is, given one of my viewmodel instances, scroll the tree view to it. This is trivial if I could just get the corresponding TreeViewItem.
Am I doing things wrong again by trying to get at the TreeViewItem, or would that be the right approach?
Take a look at Simplifying the WPF TreeView by Using the ViewModel Pattern article by Josh Smith. I hope it helps.
Admittedly this is not straightforward but you can probably still do this while keeping a separation which does not require you to access the TreeViewItems knowingly. The essence in WPF is binding as already noted by Kent Boogaart in your other question, here however you need to somehow deal with events. Your view-model needs to fire a BringIntoView event of its own while the view needs to react.
The easiest method might be to add a EventSetter on Loaded to make the TreeViewItems subscribe to said event on their DataContext which should be your view-model (if it isn't you can wait for DataContextChanged).
No, I dont see in what way accessing the items of a treeview is wrong.
I think the difficulties you are encountering are because you aren't seeing the treeview as it should be.
A leaf has a parent, but no children.
A node can have a parent, and can have children.
A node without a parent is a root.
Based on these principles (SourceMaking Composite pattern) you should be able to do whatever you want using recursivity. (in both XAML and code)
I’ve come to the conclusion that it can’t be altogether wrong. The first piece of evidence comes from Bea Stollnitz’s post about ListView: if one of the WPF developers explains how this might be done, it can’t be that wrong.
The other piece of evidence comes from this highly-voted question/answer: MVVM madness. MVVM undoubtedly has its benefits, but sometimes the cost of following MVVM is so high that it’s just silly following through with it, especially in a small one-man application. Do you really want to expose IsSelected and IsExpanded the way you’re supposed to?
As a result, I felt justified to try and figure out how to expose the TreeViewItem corresponding to an item with less effort from the developer, under the assumption that they will never need the more advanced features that resulted in TreeViewItems being this hard to access (like displaying the same ViewModels in multiple different controls... how often have you needed that!...)
I posted the result of this effort as an answer on another question.
We've created a new, quite complex, WPF application from the ground up and have run into a performance problem as the number of commands registered with the CommandManager increase. We're using simple lightweight commands in our MVVM implementation, however the third party controls we're using (Infragistics) do not, and call CommandManager.RegisterClassCommandBinding liberally to add RoutedCommands. The performance problem manifests itself as a perceived sluggishness in the UI when responding to user input, for example tabbing between controls is slow, text input is 'jerky' and popup animation is 'clunky'. When the app is first fired up the UI is snappy. As more screens containing Infragistics grids are opened the performance deteriorates.
Internally, the CommandManager has a private field named _requerySuggestedHandlers, which is a List< WeakReference>. I've used reflection to get a reference to this collection, and I've noticed that when I call .Clear(), the responsiveness of the UI improves back to its initial state. Obviously I don't want to go round clearing collections that I know little about, especially using reflection (!) but I did it to see if it would cure the performance problems, and voila it did.
Normally, this situation would clean itself up after a certain amount of time passes. However, the collection of WeakReferences (_requerySuggestedHandlers) will only get trimmed once a garbage collection is initiated, which is non-deterministic. Because of this, when we close down windows containing grids (Infragistics XamDataGrid), the CanExecute property for 'dead' grid commands continue to be evaluated unnecessarily, long after the window is closed. This also means that if we close down a number of windows, the performance is still sluggish until a garbage collect is initiated. I understand that this can happen on allocation, and I've seen that myself because if I open a further window this causes the initial memory (from the disposed Windows) to be collected and performance returns to normal.
So, given the above, here are my questions:
How, and from where, does CommandManager.InvalidateRequerySuggested() get called? I haven't found any documentation on MSDN that explains this in any great detail. I hooked up to the CommandManager.RequerySuggested event and it looks like it's being called whenever controls lose focus.
Is is possible to suppress CommandManager.InvalidateRequerySuggested() being called in response to user input?
Has anyone else run into this issue, and if so, how have you avoided it?
Thanks!
This sounds like one of the rare cases where deterministically calling GC.Collect() is the right thing to do. The ordinary argument against it is that the garbage collector is smarter than you are. But when you're dealing with WeakReference objects, you enter territory where you may know something that the garbage collector doesn't. Kicking off garbage collection is certainly better than clearing _requerySuggestedHandlers - among other things, it won't do anything to the WeakReference objects that point to controls that are still alive.
I'd choose this over trying to figure out how to suppress RequerySuggested, since that would screw up the behavior of those commands that you still care about.
If anyone can provide some help for this one, I'd be very grateful!
We are using: Silverlight 3 / MVVM / Blacklight DragDock Control / ComponentOne Silverlight Controls
I have a Silverlight application that relies heavily on the MVVM pattern. The application has seemingly been running fine, until recently. I have started to notice semi-random (semi-random = over a long enough period of time ~2 - 5 mins) I can reproduce a System.ExecutionEngineException coming from the PropertyChanged event being raised. The property name which the notification is being raised for is not always the same property name (the firing of the property change event happens in a base ViewModel class).
The code basically looks like this:
if (PropertyChanged != null) Application.Current.RootVisual.Dispatcher.BeginInvoke( () => PropertyChanged(this, new PropertyChangedEventArgs(propertyName)));
The code works for everything else in the application. Basically everything that throws off a property changed event goes through this. I'm not sure why this is failing all of a sudden. Please throw some thoughts my way.
I've been knee deep in windbg trying to get some grasp on what is going on, and still have very little. I'd by happy provide a dump or any other information that might be helpful. Obviously, there is very little information given from this particular error...
Thank you ahead of time, David Justice
A question you might ask yourself: is this ExecutionEngineException happening in IE only and, for instance, not in FireFox?
I know Silverlight is supposed to be browser-independent, but I already encountered a similar known Silverlight-issue that occured randomly in IE only.
The fact that you get an ExecutionEngineException is pointing out that the SL runtime blows up for some reason.
This exception is quite the exotic one. If one gets thrown, it's Game Over, 0 Continues for the CLR. No managed code can catch that exception.
When I ran into it, it was the result of a driver writing into a buffer that wasn't marshaled properly and so was not pinned, and the CLR moved the buffer while the driver was writing into it. It wouldn't crash instantly, but usually happened after the mouse ran over the form's menu bar (which probably resulted in creating and destroying lots of small objects, which then lead to the CLR running the GC and compacting the managed heap). Even though one of my worker threads was communicating with the driver, it was the main thread that threw the exception, which made things way more confusing.
Make sure things are being marshaled properly. If ANYTHING is being passed back and forth to unmanaged code, make sure you use GCHandle to pin the objects.
I just wasted invested a good chunk of time trying to determine why a specific datagrid among many was showing shrunken rows with no text. After many trial and errors attempts to figure out what made this grid special, I finally found that the class used for the row items was marked private.
That is a perfectly good reason, but I would have prefered to have been able to narrow it down to a binding issue (and if possible a "field is not accessable due to protection level" type message) much sooner then it took to sysmatically disassemble the entire convoluted process it took to get data into and configure that grid. Ideally I shouldn't have had to see the wrong behavoir in the first place, an error should have occured immediately when a column attempted to read from a field that it could not.
All my datagrids inherit from a custom base class in order for some global standards to be applied - if there anything I can do in my CustomDataGrid class to cause an exception to be thrown whenever a columns binding expression fails, such as if the class/property is private or the property name has been mispelled in the binding expression? (This is different from binding validation).
I always keep an eye out on debug output window when dealing with SL/WPF databinding. The framework(s) are actually pretty good at generating messages about databinding problems that include specific details about what fields it failed to bind on or what have you.
This doesn't exactly answer your original question, but it helped me sort through binding issues quite a bit once I realized there was good info being thrown into there.