.NET Framework Developer Center >
.NET Development Forums
>
Windows Presentation Foundation (WPF)
>
Disable UI ELement rendering completely?
Disable UI ELement rendering completely?
- Any way to do it?
Here is the problem. I have a window with a lot of controls on them, organized into multiple pages. THey are very active, presenting a data view from incoming high frequency streaming data.
Obviously, the controls on hidden pages (and any controls currently not visible) do not need to show ANY updates as long as they are hidden. THeir logic must run as they may create logical models of the data coming in - which means I can not easily stop the data stream.
Is there an easy way to stop all databinding on an element downward so that it can later be reenabled? Being .NET 4.0 I would also love to turn off all caching that the controls may do - I am comfortable with them redrawing when their page switches back on.
Stopping user input would be a nice side-effect, but I asssume the impact is neglegible here as the controls are not visible to start with.
All Replies
- I came up with 2 possible solutions:
1. Create bindings when the page is visible and destroy them when they become hidden/collapsed again.
2. Create the bindings with the explicit UpdateSourceTrigger and implement a method that let calls update the binding just if the specific page is visible
I haven't tested any of this yet, so I don't know a) if it really works and b) how performant it is
Tobias Both I dont like. They move the responsibility too much to the controls - the functionality should rely in the container, pretty much like virtualization.
Isn't there a mechanism to just turn binding on or off?- Hi,
what about setting the page's DataContext to null in a Trigger? If the trigger condition goes away, the trigger should set the DataContext to its previous value. You could make the Trigger dependent on the page's IsVisible property, for example. - It would interfere with the internal work of the control. VERY unrecommended - i dont want the calls from people wirintg controls to go into that place of the application and getting stumbled by that. It may work, though ;) No direct "SuspendDataBindong" method around somewhere?
- Hi,
I think I don't understand your scenario, then. As far as I understood you, you have data coming in that keeps changing an object model, and these changes should continue while you are not displaying the control, but they simply should not be forwarded to the rendering system, correct? If what I suggested doesn't work in your case, it seems for me to imply that your object model depends on the control itself. Does it? If so, a solution might be to decouple the object model from the control, and see to it that the changes to the control and its components are done through DataTemplates. In this case, setting the DataContext to nothing would disconnect the view from the ViewModel while the ViewModel keeps updating itself, and setting it back to the ViewModel would cause the view to re-synchronize itself with the model.
Now, the remark about calls from people writing controls getting in there, I completely fail to understand. What do you mean with this? - Let me start at the end. This is the core for a complex visualization application for high performance real time data. We talk about up to 20.000 updates coming in per second per window. Normally a lot is filtered out, but obviously the controls are busy. Having them on pages allows switching between multiple visual analysis. But obviously it is stupid to update the UI for something that CAN at that point not be seen because it is on another page.
As this is an extensible application, it comes with a (simple) API. COmposition of a page is really not complex thanks to XAML. I obviously want to put as few constraints on a programmer as I can. Manippulating an objects INNER state (which includes data context) may result in support cases because people will ask why their data context disappears. It also MAY interfere with some inner workings on customer written code.
I would rather keep that on the level of XAML interaction. Keep the non-visual part of the control alive, but freeze the visual presentation until I decide so (i.e. the user switches pages).
Decouplind objects models from controls etc. is nice, but it is unrealistic. Why should one do so for simple controls? Why should I force a user to do more than provide me with a valid WPF control to put on a page?
To give you an idea what we talk of:
* I have a simple control that has 4 text boxes. It shows prices - best price for purchase, best price for sale, plus the available volumes. This is simplistic (actually it does more). Anyhow, can you imagine that those fourtext boxes eat up a significant part of a CPU core? Why? well, some thousand updates coming in per second ;) As much as 1000 updates come regularly in per second. Granted, an extreme example. But why should the databinding be active at all when the control can not be visible?
And, on the other hand, why should I ask the programmer of the control to adhere to some overly complex stuff just to suspend data binding? - Hi,
sorry, I think this is getting far more lengthy than it deserves to be, since the system probably knows anyway that it shouldn't render what can't be seen.
Anyway, I'd still like to understand why I can't understand you. So, taking your example: I would have a small, non-visual data receiver class that just receives your four values, exposes the most up to date values through properties, and does nothing but firing change notification events every time the data changes, maybe a thousand a second, as it should do when the control is displayed. As far as I understood you, this updating has to continue, e.g. because there is another bit of logic somewhere that sums up or averages all the values that come in, and that should consider also values that weren't shown to the user.
Then I'd have your four TextBoxes in a UserControl. The UserControl would normally (when visible, that is) have its DataContext set to an instance of the data receiver class. Internally, the TextBoxes are bound to the properties of the class, each to one. Then the page which hosts the UserControl becomes invisible, and this would cause it to set the DataContext to null. The change notification events of the data receiver class would go on, but since no-one is listening (except perhaps this other bit of logic) they wouldn't cost much processing time. As soon as the page becomes visible again, the trigger logic restores the previous value of the DataContext, i.e. the reference to the data receiver class, and the TextBoxes start listening and updating themselves again.
Since you have the pages encapsulated in another UserControl, which is the only thing your customers will get to see, you can keep all this handling inside your control, therefore I don't understand your last objection. - There is no "suspend data binding" method. That's because there are plenty examples of bindings that should work even when their target element isn’t visible. For example, any binding on the Visibility property itself. For another example, apps can (and do) use hidden elements as a staging area for data – using data-binding to obtain and convert data that need not be directly visible on the screen, but is now available for use elsewhere in the app.
WPF cannot tell which bindings you want to suspend -- we can't read your mind. So you'll need to do something explicit and targeted to disable exactly the bindings you want. The suggestions about setting DataContext to null are steps in that direction. As you've observed, you'll have to be careful not to interfere with the normal operation of controls; however, a well-written control shouldn't depend on an externally-defined DataContext for correct behavior.
Dev Lead, Windows Presentation Foundation, WinFX- Unmarked As Answer byJustTom Friday, November 06, 2009 3:19 PM
- Marked As Answer byJim Zhou - MSFTModeratorFriday, November 06, 2009 2:29 PM
- Sam,
the main problem with setting the DataContext to NULL is..... MVVM ;) If your control logic lives in a ViewModel which is in the DataContext.... this may turn problematic. So, I am not sure I would keep up the "a well written control shouldn't depend on an externally defined DataContext for correct behavior" given that basically every MVVM approach I am aware of that is widespread injects the ViewModel into the DataContext, and often does so.... externally. Force-Removing the DataContext may result in broken behavior if property updates do not get propagated anymore - and some property udpates may come as the result of cascading update sequences on attached properties.
I am also not sure how it would interfere with any data binding. If I suspend data binding... would it not reevaluate all bindings when reeenabled? I think I can write that as behavior on the controller - go through all bindings, suspend them, then, on reenable, trigger them. I simply dont see a reason where this can go wrong ;) Seriously. If Visibility is data bound, the moment I suspend it, suspend it. The moment I reenable it... reenable it, and trigger it ;)
If you dont want to implicitely trigger an explicit trigger.... then put a marker into the binding remembering it needs to execute. And only trigger it if the market has been set. Data Binding architecture should IMHO be powerfull enough to suspend (possibly expensive) updates on controls which make little sense to execute them. THis is not a lot more complicated than, for example, visualization - I just want to stop the visual tree from updating. YOu dont really go in and tell me you don't interfere with the normal operation of a control when I dump it into some other control that virtualized the presentation, or? - Ok, i have to reeactivate that again. In the light of more research, Sam, your answer makes no sense. Sorry.
Because WPF has the ability already in certain controls to do exactly what I ask for - acutally by even going further by totally destroying the visual tree of the controls.
Also known as, to my understanding - by Virtualizing, in the VirtualizingStackPanel. Now, this actually is even better than what I originally wanted, it seems.
Any documentation on how to implement my own virtualization (on 4.0 beta 2, mind you, which seems to have better Virtualizaton support)?
From what I understand it would mean I would keep the logical tree intact (and that means the objects exist, the controls keep running) while getting rid of the visual presentation ;) Perfectly for what I want ;) Sadly I am more in the "Grid" type of presentation (the pages are organized in a grid like fashion, though they can reorganize the grid, for example, if a control is zoomed in), so the virtualization stack panel is a little - wrong to start ;) - Hi,
I feel like we are talking different worlds, but I'd like to give it one last try:
When reading what you write, I have the feeling that you use WPF like people used to use Windows Forms, instantiating controls and control items like ListViewItems etc. in code.
Actually, in WPF these things are taken care of through data binding and data templates. Setting the DataContext property of a control to null doesn't mean that the inner structure of your control falls apart. Actually, all dependencies between the control and the incoming data should be through data bindings. And if the DataContext is set to null, these bindings still keep in place, they just stop producing values, thus stopping to consume CPU time. If some elements inside the control are produced by DataTemplates, these elements get freed, just to be reinstantiated the same way they were when they are needed again. If the DataContext is set to something new, the information is just channelled through the internal binding structure of the control and starts coming in again.
As Sam already wrote, a well-written control should not be dependent on an externally defined DataContext in order to function correctly. If you need to hold on the the data objects your customers provide, well, no problem at all, just wrap your control into another layer, e.g. through a user control, and disconnect the connection internally.
Sorry, this all seems so obvious to me...
http://wpfglue.wordpress.com


