ExtJS PropertyGrid high frequency update - extjs

Is there a good way of updating the values displayed in an ExtJS 4 PropertyGrid many times a second?
Calling setSource works, but it triggers a full re-render of the component, hammering the component layout and making things like scrollbars unresponsive.

I must say I never used propertyGrids that much but in case o high frequent changes I would directly write to the dom and ensure (along with each writing or a trigger) that no events gets bubbled up to ExtJS.
Anyway, I am pretty sure that any change to the bound store will also affect the value. setSource is just a way to apply data that get also inserted into the store. But this will always change all and I guess override any existing data (the last I don't know for sure)
But you can also use setProperty to change a single property. May that one is enough. Worth a try.

Related

Changing ListView.ShowItemToolTips raises ItemChecked events

Hi when I set ShowItemToolTips of a ListView with checkbox items to true in designer and change it to false in the code, the event ItemChecked is raised. The checked state itself is not changed though. But inside the (also raised) ItemCheck event the old value is not equal to the new value but the new value is the value that was previously visible. It seems like the items are re-inserted or reset in some way.
I tested this on two machines and projects. Why does this happen and how can I avoid it?
I'll explain the "why", a workaround is hard to come by. Some control properties are very impactful and can have odd side-effects when you change them. Like ShowItemToolTips, changing it after the ListView is created requires Winforms to completely destroy the native control and recreate it from scratch. Under the hood, it is a style flag (LVS_EX_INFOTIP) that's specified in the CreateWindowEx() call. The Control.RecreateHandle() method ensures it is effective. You'll see the flicker that this causes if you look closely.
So for a brief moment, the native control exists without yet being initialized with the original checkbox states. Getting a flaky event for that is a bug, but it is the kind that was either never fixed because doing so was too difficult or was just never discovered because nobody ever changes the ShowItemToolTips property after the control was created. It is very uncommon to do so.
In general, this native control re-creation trick has been a significant bug generator in Winforms. And workarounds are hard to come by, they fit either in the "deal with it" or the "don't do it" category. With the latter one strongly recommended in this case.

How to optimize TreeNode name change?

I have a TreeView which holds approximately 100,000 TreeNodes or even more, I have optimized everything related to loading or unloading them on deserialization process but now I'm stuck with an issue I can't overcome.
Its important to mention I decided not to use the LabelEdit default event given by the control since its pretty tricky to make it work as I wanted to, Its widely known that there are a lot of "problems" with this particular event which have pushed many devs to implement their own custom TreeViews.
In my case I am using a ContextMenu which has a Rename option, this brings a textbox right in front of the TreeNode and then I just simply change the TreeNode.Text property to whatever the user input was in the TextBox keydown event, once we trigger this event, the whole GUI freezes for a couple of seconds (4-5), I'm not doing any Depth search over the TreeNodeCollection or anything, I am directly accessing the TreeNode and modifying the property...
So, any thoughts on what could be wrong here? I already tried BeginUpdate / SuspendLayout / or even a custom solution found here How do I suspend painting for a control and its children? and nothing seems to help.
The first thing that comes to mind is that when the text is changed on the node, it must be redrawing the entire treeview.
In this situation, suspendlayout will not help, as the control isn't laying its contents.
I think beginupdate stops the drawing when nodes are being added to the list, but the text changed might bypass this.
Have you considered not using the keydown, and just updating the text once the user has dismissed the textbox? (i.e. done editing). Not ideal, but will limit the performance hit to once, instead of every key stroke?

How to cache components of a huge Application

I need to setup a quite huge Application with arround >20 main views plus forms. A mainview will at least contain one grid but can contain upto ten grids. There are also some mainviews that contains a Portal-Panel.
Now it comes that it take quite some time till a mainview opens which don't happends as I tested it with just one instead of >20. The Application lays within a Viewport with fit layout which holds a container with Borderlayout. The Mainview always render within the center while the other regions are used for navigation.
My first approach caching things within a tabpanel
My first approach was to got with a Tab-Panel with hidden tabs. Parallel to that I manage a MixedCollection where I make lookups if the View has already been inserted into the tabpanel or has to be created. If it has already been inserted I fetch the positon from the MixedCollection and run the setActiveTab(). But it seems worthless cause it takes all the same time to insert a new mainview or to activate a existing with setActiveTab().
So what I am doing wrong and how can I make this better?
Edit
The problem seems to come from the rendertime and that the component seems to get reredenred each time setActiveTab() is used. It takes up to 2-3 secs to render a view into the center panel. Therefore I thought I can be speed it up by caching a already created view so that the rendering and sizing didn't need to be done. I guess I should mention that in the north region a menu is also rendered each time, which not get's chached but that shouldn't matter, shouldn't it?
How the views are switched
I have a extra controller that manages the menue-view and the main-view changes. For that the menue gets removed from the container and the new menue is added and for the main-view a lookup is done in the mentioned mixed-collection if the view has already been created and if so the tab-index is received and the tab activated. If not the view get added as new tab and is afterwards added with it's ident and index to the mixed collection.
It may help you to take a look at suspendLayouts() and resumeLayouts()
You run Ext.suspendLayouts(); before you begin changing the views and Ext.resumeLayouts(true) after you are done with all views.
You should also check for overnesting, meaning you have nested to much components into each other.
Example:
If a grid is the only component within a tabpanel then it would be overnesting if you place that grid in a extra panel and then into the tabpanel.
Firstly what I found that non active tabs will be populated anyway. I don't know why. But my stores for not active tabs loaded anyway.
Second, it is really doesn't matter the size of your app. We have a lot of views and everything works pretty fast.
In most cases it is depends:
First is nesting - review your code. Less nesting more speed. For example instead of panel if you dont need all stuff that panel provide- use container. Because all this stuff is add more divs to your dom.
Depends how you create your view. Without your code it is really hard to say, why it is slow. Maybe you create your view every time when you open tab, or go to another view.
As mention #sra try to use suspendLayouts - it means that your browser will render your stuff only resumeLayouts, instead of rerender everything everytime when you add any component.
If you use windows - use closeAction:hide instead of destroy.
Not use Ext.getCmp(). I also hear that refs can slow down application because they start searching your component from the body. But it not proved info :) Use component.down('id'), component.up('xtype') it will search only from your component not from the body.
Not create your view from controller everytime when you do something using Ext.create('Panel'). It means it will created everytime.
Use less global events because this is also slowdown your app.
It is really hard to say what is the issue in your case without code. This is only few point that can help you. But my suggestion to looking to nesting and how and where you create a view.

TextBox UpdateSourceTrigger = PropertyChanged - does it really affect performance?

The MSDN documentation states:
Bindings that are TwoWay or
OneWayToSource listen for changes in
the target property and propagate them
back to the source. This is known as
updating the source. Usually, these
updates happen whenever the target
property changes. This is fine for
check boxes and other simple controls,
but it is usually not appropriate for
text fields. Updating after every
keystroke can diminish performance and
it denies the user the usual
opportunity to backspace and fix
typing errors before committing to the
new value. Therefore, the default
UpdateSourceTrigger value of the Text
property is LostFocus and not
PropertyChanged.
I understand that in a situation where the update is going directly to a database, or across a network, or if it's an extremely large amount of data, that it could indeed diminish performance to use UpdateSourceTrigger = PropertyChanged on TextBoxes.
But if it is just updating a simple DependencyProperty, or a property of an Entity Framework object (prior to committing), would the performance hit not be negligible?
Just wondering, because I am creating a WPF app which tracks the state of the object being edited and optimizes the Save button appearance depending on whether changes have been made. I thought the easiest way to determine changes would be to catch the relevant SourceUpdated occurences as appropriate. It works optimally when UpdateSourceTrigger = PropertyChanged for the textboxes, as the user gets instant feedback that there are "saveable" changes.
The reason that you're warned about performance degradation is that for the most part, if you need to have the source property updated on every keystroke, it's because you need something to happen when the property's value changes. After all, if you didn't need that "something" to happen, you wouldn't really care when the property got updated, so long as it did eventually.
The real impact on performance depends entirely on what that "something" is. And that's totally dependent on your application. If that "something" is formatting and displaying the value in another TextBlock, doing it on every keystroke probably won't be noticeable. If it's filtering a 10,000-row DataTable and refreshing a DataGrid bound to it, it probably will.
So how do you tell? Well, there are two ways:
1) Understand your application. If you know what the application is doing when you update the source property, you can predict whether or not doing it on every keystroke is going to be a problem. When you say "I guess I was wondering whether it might seem to be fine at first, but can actually cause issues in certain situations I'm not aware of," what you're really saying is, "What happens if I don't know what my application is doing when the user presses a key?"
2) If you don't know what your application is doing when the user presses a key, profile it.
If it is suitable for your application and you don't notice a significant degradation in performance, then there is no problem setting the UpdateSourceTrigger to be PropertyChanged. In fact, if you're using an MVVM framework such as Caliburn.Micro, then it will set this as the default setting for all TextBoxes.

A better way of managing a forms state?

I am new to Windows programming, as in my previous work I've mostly been involved with web technologies, and mostly in the backend. I have inherited a Winforms application, and one of my biggest nightmares is navigating through the endless states a form can be in.
To give you an example, a form has the state 'New' and 'Edit' depending on whether the user decided to Add or Edit a record. On this form, we have logic. If this texbox has a certain value, then these other textboxes are disabled, etc. This leads to endless chaining of these rules. So, a textbox's TextChanged event will influence another field. It in turn will fire X event that changes the state of other controls. It quickly devolves into a tangled mess that is impossible to maintain.
There has to be a better way... something simple and elegant that solves this problem. Any suggestions?
What I do is to have a single method called FormatControls(). In this method, I implement all the logic such as myTextbox.Enabled = mycheckBox.Checked and so on.
I call this method from my event handlers in the form, such as on checked changed, etc... I also call it when appropriate (ie, form newly loaded with no data, record loaded from database, etc). This has suited me well for many years now, it makes everything less complex.
You are correct, if you do not have a pattern in use it can turn into a too-complex thing.
You can try to use tha Application.Idle event to perform the enable disable logic and insulate this part from the business logic part.
Depending on what controls you have on your form, you might be able to do away with the separate textboxes and add/delete buttons and replace the whole works with a DataGrid.

Resources