I have a large number of styles defined for my grid (cell colors based on state, etc.). Right now I use DataTriggers to set the appropriate colors. I am looking to improve the performance of my app and was thinking that the large number of styles may be causing a slow down (due to the data changing constantly and the styles needing to be recalculated/refreshed). Is it better to use data binding with converters instead of DataTriggers?
If the goal can be achieved using either method, is there any performance difference? I am not familiar with what is going on behind the scenes so I can't be sure.
In this episode of the Hanselminutes podcast, guest Laurent Bugnion (creator of MVVM Light) describes that there is a performance hit associated with using converters. He indicates that it is almost always negligible in desktop applications, but that in WP7 applications, it is recommended that viewmodels expose things like brushes directly, rather than relying heavily on converters, especially if dealing with list virtualization, in which case scrolling will cause many invocations of the conversion.
It is possible that a similar thing is occurring in your scenario, just given the volume of triggers (or conversions if you made that switch).
As a proof of concept, you might consider wrapping your view-model in a "WPF Viewmodel," that exposes the colors and other WPF-specific values themselves, rather than some value from which the colors can be determined by the runtime invoking triggers and IValueConverters. You'll then be able to bind directly to that, and use neither triggers nor converters. I'd be interested to hear the results.
Related
I've seen many data binding frameworks, such as WPF, AngularJS(Javascript), JSTL(JSP).
They are trying to separate UI and Data completely.
However, one main problem is that it adds complexity. Sometime, you have to write a lot of extra code (for example to extend a view class) just for one line of UI code.
In modern applications, there are many transition animations when changing one UI element from one state to another state. When use data binding framework, it seems not easy.
Are there any other cons of using a data binding framework?
For example, to set focus on a text input, so complex in AngularJS, See:
How to set focus on input field?
All of the following refers to the WPF.
You have to write a lot of extra code (for example to extend a view class) just for one line of UI code.
With regard to the WPF, this is rare situation, you can give an example?
There are many transition animations when changing one UI element from one state to another state.
In WPF since version .NET 3.5 appeared VisualStateManager:
The VisualStateManager enables you to specify states for a control, the appearance of a control when it is in a certain state, and when a control changes states.
His goal - is to define the application state, and each state to do an action, such as an animation. In this situation Binding is not used as such.
When use data binding framework, it seems not easy.
I do not think it's disadvantage. Data Binding needed as you mentioned: separate UI and Data completely. In fact, the whole MVVM pattern is based on a powerful technology as Data Binding. This feature allows you to create an abstract connection between Model and View via ViewModel. And the key word is Data, everywhere where there is work with the data, it is better to use Data Binding.
Binding allows you to do many interesting things, such as Validation, Converters and much more. It is typically used for Binding properties, and nothing more. To work with the UI using other features like VisualStateManager, Triggers, DataTriggers, etc. and it is not difficult when you use it to its destination, just need to get used to.
The only downside - is that Binding can be used for other purposes, such as use of the Converter when you can not do without it. And yes, at first it may seem unusual, but I do not think that this a drawback, the same can be said about other technologies.
Even as a drawback can be said about the performance. If you assign a value directly or via Binding, assigning a value directly will be faster. But I think that the advantages of Bindings allow not pay much attention to it.
Me and my colleagues are investigating how to replace 3rd party WinForms controlls by our new UI controls in our large legacy codebase. Practically we would like to replace the 3rd party controlls in the inheritance chain. The 3rd party controlls are used dozens of places by subclassing the 3rd party UI controlls. We d like to perform this change as safety as possible, with minimal code change all over the solution. Do you have any experience how to start? Obviously the inheritance means strong coupling here, so i d like to find the less painful solution here.
Is the "branch by abstraction" concept applicable here?
This is a pretty subjective decision based on your team's understanding of the code base as well as workflow. The bright side is that you've already subclassed all the controls, so you've already done the tedious work of being able to provide whatever properties the code is looking for to compile.
Given that this is WinForms, this should be much more straightforward, since the control sizes and locations are set on the Control level. You need to worry about mapping properties/methods that exist in the old vendor's controls to your new controls and not as much about form layout. This might be straightforward for some controls and more complex for others (i.e. grids).
The biggest roadblock IMO is going to be handling the current design-time serialized logic in InitializeComponent. If you've created a property to map from old -> new, you're going to have to be careful that when the designer re-serializes everything after you open the form and modify something, you might not want to serialize both the old property and the new. As an example:
Old Vendor
this.myOldComponent.Data = this.dataSource;
New Vendor
this.myNewComponent.DataSource = this.dataSource;
In this case, you may consider creating a new property called Data on your subclassed new component so that the old code works without changing anything. Let's say you open the form in the designed and move the grid a few pixels, causing the designer to serialize the data. You might now have:
this.myNewComponent.Data = this.dataSource;
this.myNewComponent.DataSource = this.dataSource;
You can prevent serialization with attributes (good discussion on it in this SO question, but this is just an example of something you might hit.
I don't think there's really a pattern here to follow, unless you mean on the source control level, in which case I would say to absolutely create a new branch apart from your regular development one; who knows what kinds of roadblocks you may hit and you'd want to shelve your work for a bit.
Ultimately, you may decide that it's just best to suck it up and rip out the old components and put in the new, but as mentioned this is very subjective. It's situations like this that make me really love WPF and the MVVM model, since you could entirely rip out the UI and keep the business logic intact.
We're rolling our own special Items-based control/panel combo that isn't based on a subclass of ItemsControl (there are multiple reasons why we can't do this which I won't get into here) but our control does handle thousands and thousands of data items, so we'd like to implement Visual virtualization.
What we're wondering is if it makes more sense to try and bang the existing ItemContainerGenerator class into our design or roll our own virtualization method.
On the one hand, ItemContainerGenerator already handles virtualization and is very efficient, and tried-and-true code is almost always preferable to starting from scratch, but on the other, the ICG was designed specificially for use with, and relies on features of the ItemsControl, which again, this control is not. Plus, that is a container generator but in our case, we just need to generate and lay out a specific, known visual that represents the data item.
Now, perhaps I'm over-simplifying things, but all I see is a need to determine which items would be visible in the ViewPort, ensure visual representations of those items are created, measured and arranged, then discard any left-over already-created visuals. To keep track of it all, it seems a simple item-to-visual mapping scheme is all that is needed, perhaps with a ItemVisual attached property on the DataItem's ViewModel object. That way when an item is removed/destroyed, we just check if there's an existing visual, and if so, nuke it.
That said, can anyone think of a reason we shouldn't simply roll our own visual virtualization? Again, the ICG does this, but I'm wondering if that's taking a Semi to the store to get eggs.
In case a screen of a WPF application contains lots of primitive controls, its rendering becomes sluggish. What are the recommended ways to improve the responsiveness of a WPF application in such a case, apart from adding fewer controls and using more powerful videocard?
Is there a way to somehow use offscreen buffering or something like that?
Our team was faced with problems of rendering performance. In our case we have about 400 transport units and we should render chart of every unit with a lot of details (text labels, special marks, different geometries etc.).
In first our implementations we splitted each chart into primitives and composed whole unit's chart via Binding. It was very sad expirience. UI reaction was extremely slow.
So we decided to create one UI element per each unit, and render chart with DrawingContext. Although this was much better in performance aspect, we spent about one month improving rendering.
Some advices:
Cache everything. Brushes, Colors, Geometries, Formatted Texts, Glyphs. (For example we have two classes: RenderTools and TextCache. Rendering process of each unit addresses to shared instance of both classes. So if two charts have the same text, its preparation is executed just once.)
Freeze Freezable, if you are planning to use it for a long time. Especially geometries. Complex unfreezed geometries execute HitTest extremely slow.
Choose the fastest ways of rendering of each primitive. For example, there is about 6 ways of text rendering, but the fastest is DrawingContext.DrawGlyphs.
Use profiler to discover hot spots. For example, in our project we had geometries cache and rendered appropriate of them on demand. It seemed to be, that no improvements are possible. But one day we thought what if we will render geometries one time and cache ready visuals? In our case such approach happened acceptable. Our unit's chart has just several states. When data of chart is changed, we rebuild DrawingVisual for each state and put them into cache.
Of course, this way needs some investments, it's dull and boring work, but result is awesome.
By the way: when we turned on WPF caching option (you could find link in answers), our app hung up.
I've had the same perf issue with a heavily customized datagrid since one year, and My conclusion is:
there is basically nothing you can do
on your side (without affecting your
app, i.e.: having fewer controls or
using only default styles)
The link mentioned by Jens is great but useless in your case.
The "Optimizing WPF Application Performance" link provided by NVM is almost equally useless in my experience: it just appeals to common sense and I am confident you won't learn anything extraordinary either reading. Except one thing maybe: I must say this link taught me to put as much as I can in my app's resources. Because WPF does not reinstanciate anything you put in resource, it simply reuses the same resource over and over. So put as much as you can in there (styles, brushes, templates, fonts...)
all in all, there is simply no way to make things go faster in WPF just by checking an option or turning off an other. You can just pray MS rework their rendering layer in the near future to optimize it and in the meantime, try to reduce your need for effects, customized controls and so on...
Have a look at the new (.NET 4.0) caching option. (See here.)
I have met a similar problem and want to share my thoughts and founds. The original problem is caused by a virtualized list box that displays about 25 complex controls (a grid with a text block and a few buttons inside displaying some paths )
To research the issue I used the VisualStudio Application Timeline that allows to how much time it takes to render each control and PerfView to find out what actually WPF is doing to render each control.
By default it took about 12ms to render each item. It is rather long if you need to update the list dynamically.
It is difficult to use PerfView to analyse what heppens inside since WPF renders item in the parent-child hierarchy, but I got the common understanding about internall processes.
WPF does following to render each item in the list:
Parse template using XAML reader. As far as I can see the XAML parsing is the biggest issue.
Apply styles
Apply bindings
It does not take a lot of time to apply styles and bindings.
I did following to improve performance:
Each button has its own template and it takes a lot of time to render it. I replaced Buttons with Borders. It takes about 4-5ms to render each item after that.
Move all element settings to styles. About 3ms.
Create a custom item control with a single grid in the template. I create all child elements in code and apply styles using TryFindResources method. About 2ms in the result.
After all these changes, performance looks fine but still most time is spent on loding the ListControl.Item template and the custom control template.
4. The last step: replace a ListControl with Canvas and Scrollbar controls. Now all items are created at runtime and position is calculated manually using the MeasureOverride and ArrangeOverride methods. Now it takes <1ms to render each item from which 0.5ms is spent on TextBlock rendering.
I still use styles and bindings since they do not affect performance a lot when data is changed. You can imagine that this is not a WPF solution. But I fave a few similar lists in the application and it is possible not to use templates at all.
I'm having trouble deciding what to think about this piece of code:
public SolidColorBrush Brush
{
get { return IsValid ? _validItemBrush : _invalidItemBrush; }
}
It is part of a view model in my current project and as you can imagine, the Brush will be bound to some text elements in the UI, to indicate (in-)validity of other pieces of data, in an otherwise fairly simple and straightforward dialog.
The proponents of this piece of code say that since we're using WPF, we might as well allow for some simple WPF specific constructs in the view model.
The opponents say that this violates Separation of Concerns, as it clearly dictates style which should be taken care of solely by the view.
Please share your arguments, and if you're not happy with the code above, please share your ideas around alternative solutions. (I'm particularly interested in what you have to say about using DataTemplates).
Is it possible that there is one solution that could be considered best practice?
Personally, I would have the two brushes be defined in XAML, and have the controls that use them switch brushes (in xaml) based on the IsValid property. This could be done very easily with DataTriggers, or even a single IValueConverter - the converter could take 2 brushes and a boolean and swap between them fairly easily.
This keeps the business logic presentation-neutral - a "Brush" is very specific to a specific form of presentation, and a pure View choice. Hard-coding this into the ViewModel violates the single responsibility principle as well as is not a clean separation of concerns.
I would very much keep this in the View, and switch based on the IsValid (bound) property that is ViewModel specific.
While there are circumstances where I might use WPF constructs in the view model, this isn't one of them. Here's why:
It's harder to change. If you define brushes as resources and use them in styles, changing your application's color scheme can simply be a matter of loading a different resource dictionary. If you hard-code color values in your view models, you have a lot of different things to change if it turns out your end users need different colors.
It's harder to test. If you want to write a unit test that checks to see if a property is returning the right brush, you have to create a brush in your unit test and compare the values of the two, since it's a reference type.
In many, maybe even most cases, it doesn't make the code simpler or easier to maintain. You're pretty likely to already be using a style (assuming that you are conversant with styles), since they make just about everything in WPF easier. Binding IsValid to brush colors is just a matter of adding a DataTrigger to a style. Which is where anyone maintaining this code would expect to find it.
There are certainly times when I do use WPF constructs in the view model - for instance, long ago stopped wondering if it was problem if a view model exposed a property of type Visibility. Note that none of the above concerns apply to that case.
In cases like yours where it's purely aesthetic I use Triggers or the Visual State Manager to change colors.
Sometimes I do use colors in my ViewModels, but only if its part of my software spec (e.g., the color of the chart displaying a patient's CO2 depends on localization). In that case, I use a Color struct bound property, allowing the View to use the Color for a SolidColorBrush, a GradientStop, or whatever it wants. I initially used a string in #AARRGGBB format to completely remove the WPF dependency but my more seasoned co-workers didn't like that.