ContentPresenter.Loaded not raised when the control is initially created as collapsed - windows-phone-7

Perhaps hoping in a miracle, but let's try :-)
MyControl derives from Control. Its ControlTemplate contains
<ContentPresenter ContentTemplate="{TemplateBinding EditorTemplate}"/>
(Other details are omitted.)
Derived controls supply suitable EditorTemplate. For example MyTextControl specifies template consisting of a TextBox. (With proper bindings, of course.)
I won't describe what works (most scenarios), but what does not:
A collapsed MyTextControl instance is created. Later on this control is made visible. Here is what happens:
MyTextControl instance created, set to Collapsed
MyTextControl.Loaded event: At this moment the visual tree contains MyTextControl with no children.
In the Loaded handler I call ApplyTemplate(). In turn the visual tree is modified to MyTextControl -> ContentPresenter. That's all, no more children.
Stil in Loaded handler, I assign Loaded handler to the ContentPresenter.
Sometimes later the control is made visible. Its visual tree gets populated by TextBox internals: Border -> ContentControl -> ContentPresenter -> internal TextBoxView. In other words the control just works.
The problem is that the ContentPresenter Loaded handler was not called, i.e. I am not able to identify the moment when the control is ready.
I tried an alternative solution, i.e. instead of forcing ApplyTemplate() I simply waited in MyControl.OnApplyTemplate(). The sequence:
MyTextControl instance created, set to Collapsed
In the Loaded handler the visual tree contains MyTextControl with no children.
The control is made visible.
In OnApplyTemplate() the visual tree is MyTextControl->ContentPresenter.
Stil in OnApplyTemplate(), I assign Loaded handler to the ContentPresenter.
The rest is as before. The visual tree is populated by TextBox internals (the control works), but the above handler gets not called.
Does anybody know a way how to identify the moment when the control is fully loaded?
Note that I did the above with several other MyControl-derived controls. For each of them one of the above scenarios worked (sometimes one, sometimes another), but the TextBox-based control is the first one where I am not able to identify moment of loading.
Also note that this problem does not happen when the control is visible for all the time.

Ok, I'll answer myself. My current conclusion after 1 day and dozens of tests is that Loaded event is for birds. It happens on various stages of the control life cycle and in case of composite controls there is no warranty that the control is fully functional. In some cases it might be not fired at all.
Forcing template building by calling ApplyTemplate() is no solution either as in some cases it may result in building partial control tree.
OnApplyTemplate suffers similar problems - it might be called when only partial control tree is built.
After acknowledging the above statements I decided to give a try to LayoutUpdated event. I set up the handler in OnApplyTemplate() (I tried to use latest possible moment) and investigated the control tree. As a first approximation it seems to be sufficient to check if the ContentPresenter has children. If so, we'll say that the control is loaded and unregister LayoutUpdated handler. A more sofisticated test could be used, but the trivial one I just described is working for wide range of controls.
Originally I was afraid that the LayoutUpdated solution will be inefficient, but it looks like (using the described organization) the first handler call is exactly the place when the control is "loaded".

Related

How to intercept the changes to this properties window?

I'm trying to intercept the change events triggered (any field) when this property window is changed in a VS Extension project (vsix). This extension will target VS versions upto 2019 (the latest one).
I've used dte.Events.TextEditorEvents.LineChanged but it captures the event intermittently.
Is there a specific event that I can look at for this purpose?
Initially I mistakenly thought IVsRunningDocTableEvents.OnAfterAttributeChange could be used. But after reviewing the designer code base (one of the few I've seen written in VB.NET), I found that this particular designer sets the windowframe's dirty by explicitly invoking IVsWindowFrame.SetProperty with VSFPROPID_OverrideDirtyState, which per the comments in the vsshell80.idl file:
VSFPROPID_OverrideDirtyState = -4014, // BOOL/EMPTY -- tri-state value to control dirty star (*) in window caption
// VT_EMPTY: default handling of dirty star
// VARIANT_TRUE: override default handling to SHOW dirty star
// VARIANT_FALSE: override default handling to show NO dirty star
indicates this designer doesn't leverage the default mechanism driven by the RDT. :-(
The only notification I could find that you could possibly intercept would be an IPropertyNotifyChange on the individual properties themselves, which does fire, as soon as you change a given setting and move focus to another control.
This may not be what you're looking for, but if you can explain why you need such a notification, I may be able to come up with something better than periodically polling the designers VSFPROPID_OverrideDirtyState property (which is the only other thing that immediately comes to mind).
Thanks,
Ed....

Angular2 OnPush change detection and ngFor

I have a parent component that displays a list of child components using ngFor. I noticed that performance gets really bad with increasing number of children so I have changed both to OnPush change detection strategy.
That helped a lot, but there are still few scenarios when it slows down and I can see thats due to change detection being executed for each of the children unnecessarily.
One example is when there is a click event inside the child component - even though no inputs is changed and its just triggering an animation, for some reason the change detection is being executed for parent component and as a result for each child component as well (even though the model behind ngFor doesnt change at all and its a OnPush strategy...). I would have thought that this kind of "isolated" event should only trigger change detection in that particular child component and not propagate up (I have actually tried event.stopPropagation() and event.preventDefault() with no success).
So I was wondering two things:
1) is there any way of having more control for what events change detection actually runs and whether it triggers the parent component change detecion as well?
2) is using "translate" pipes quite a lot in each child component (from ng2translate) could slow the application/change detection a lot?
Sample plunkr below to show what the problem is. Basically if I click on any of the item in ngFor list, it kicks of change detection for every single child rather than only the affected one and I was wondering if there is any way of suppressing that.
https://plnkr.co/edit/mD8HCbwq0cEwPt7itpCf
1) You can use ChangeDetectorRef.detach()
https://angular.io/docs/js/latest/api/core/index/ChangeDetectorRef-class.html#!#detach-anchor
Detaches the change detector from the change detector tree.
The detached change detector will not be checked until it is reattached.
This can also be used in combination with ChangeDetectorRef to implement local change detection checks.
2) pipes (if they are pure, which is the default) are only called when piped values or parameters change, therefore there is no performance disadvantage.

Can I improve upon window redraw and if so how can I?

Some years ago (2008) I wrote an online Child Support Calculator using PHP/Javascript/Ajax/css Advanced Child Support Calculator - May help to explain what I am replicating.
Some time after (2009 I think) I started writing an equivalent for Windows and am now revisiting this. The fundamentals of this version are working.
However, I have an issue with the window noticeably flickering/changing when controls are dynamically added and the window is redrawn/rebuilt.
Note! This calculator is specific to Australia.
In short I'm looking for a way, if possible, to only refresh/re-display/redraw the window after all components have been added.
Basically, the windows controls need to be dynamically added/removed depending upon the scenario (number of adults and children involved).
Adding or removing a child or adult or performing the calculation, results in a complete rebuild of the window. That is, all existing controls are destroyed and then all valid controls are added (this could perhaps be minimised via complex logic).
The issue is that controls are removed but briefly reappear (in an ordered fashion) causing the display to flicker (for want of a better description).
The following screen shots demonstrate the complexity factor (such as a child has a drop down for each defined adult), but not the flicckering(sic).
Here's a screen shot of the Initial display (OK pretty ugly at present) :-
And then if an Adult is added (note that the child now has an extra dropdown for Adult 3, the new adult):-
And now, an Adult (as above) and a Child:-
Coding wise, there is a RebuildAll function. This has two main stages. (1) The removal of the controls. (2) The rebuild (recreation) of the appropriate of the controls (Create Window, SendMessage's and then ShowWindow)
At a minimum there are 61 controls. The number of controls is
23 + ((#children * 12) - 2) + (#children * (#Adults * 8 )) + ((#adults * 10) -4). It's likely suffice to say that the number of controls increases rapidly/exponentially.
I suspect that it might be possible to postpone the ShowWindow untill after all of the builds have been done. Is the solution, as simple (theoretically) as this, assuming that this is feasible or is there another way that would circumvent the need to change all the code to remove the 'ShowWindow' and add a ShowWindow at the end of the builds?
Note replacing the individual ShowWindow's with one significantly reduced the "flicker" but didn't eliminate it. (as per Update below).
As an endnote I'm pretty sure that something should be feasible as the
windows program I have to date is a very poor reflection of the speed
of the browser/javascript version, which basically does the same thing
on windows (albeit 64bit).
Update
I went through and commented out the ShowWindows in all the AddItem???? functions and added a ShowWindows to the function that calls all the functions. This has improved matters. However, the numerous DestroyWindow calls still causes flickering when removing all of the controls. So now I guess that I'm looking for something that can disable them apparently doing an equivalent of ShowWindow.
Update 2
I have found SendMessage(hwnd, WM_SETREDRAW, FALSE, 0); (TRUE to turn drawing back on). However, this appears to supress the DestroyWindow in that the display aspect of the control remains (the controls themselves don't appear to respond though).
By a process of elimination I have cured the flicker with a combination of ShowWindow's and WM_SETREDRAW's at pertinent points.
To briefly re-describe the issue. When adding a child or adult, or performing a calculation. The entire display is rebuilt. The rebuild basically consists of 2 phases. First, destroying the existing control windows and then adding the new/replacement set of window's controls.
The resolution was to :-
Issue a ShowWindow(hwnd,SW_SHOW); (for the main/containing
window) after all the pre-existing windows control's had been
destroyed.
Issue a WM_SETREDRAW FALSE message as per SendMessage(hwnd,
WM_SETREDRAW, FALSE, 0); before rebuilding the windows controls.
Without any ShowWindow's being used.
Build the windows controls via the various functions.
Finally, when all the windows controls have been built, issue a
ShowWindow(hwnd,SW_SHOW); (for the main/containing window).
Rather than seeing the controls appear and then disappear, "the flickering". The window is blank for a while and then the controls are displayed all at once.
I'm still confused about what is actually going on though, due to:-
After some thought I decided to use a MessageBox after all the destroys. When the message was displayed the window was blank. However, when the button was clicked and processing resumed then, in situations when the number of controls was relatively high, controls would appear and then disappear in an orderly fashion, albeit it momentarily.
My guess, is that creating a control in an area where an existing
control had been, was causing that previous control to momentarily
display.

Checking a Win32 Tree View Item Automatically Checks all Child Items

I am using the Win32 API and MS Visual C++ 6 to build a tree view of a directory structure, with check boxes associated with each tree view item. My goal is to be able to check a parent folder, and have that automatically check all of its associated children.
However, after digging through MSDN, I have not been able to find a control notification message for an item being checked, only when an item is selected. I have considered using a selection notification message to prompt the program to poll the item and see if its current 'check state' is true, but I am not sure that checked and selected can be tied together in such a way, and am also concerned about the overhead associated with constantly polling items as a user moves through a very large directory.
Has anyone had experience setting up this scenario? Are my concerns about the overhead of polling a GUI element justified?
There isn't any notification. You can write your own, though. Just handle mouse click and use hittest to see if the mouse cursor is on the state image. For completeness handle the space key and send the same notification for the selected item too.
As of Windows Vista, Microsoft has introduced NM_TVSTATEIMAGECHANGING and a corresponding NMTVSTATEIMAGECHANGING structure. I'm not sure why this is not documented with the Tree View notifications but instead in the General Control Reference section.
This notification code is sent by the tree control when the state image is changing (i.e. when the check box is clicked).
The NMTVSTATEIMAGECHANGING struct has a iOldStateImageIndex and iNewStateImageIndex field that specifies the corresponding change. This information can be used to determine the new state image that will be displayed (1 is the unchecked box and 2 is the checked box)
Vista also introduces dimmed, partial and excluded checks though at the moment I'm not sure how those are represented by the state image index as the two base cases above.
Here is the best way by MSDN (TreeView::AfterCheck Event):
http://msdn.microsoft.com/en-us/library/system.windows.forms.treeview.aftercheck(v=vs.110).aspx

What is the bubbling concept?

I've heard of events and SO answers "bubbling up", but what has all that got to do with bubbles?
Event bubbling is the idea of information moving up through a deep structure, when proper design dictates that normally information should only flow downward.
In very basic terms, think of a single object. Properly designed, this object should only know about its own child objects. It should have no direct interaction with its parent. Its children and parent objects, in turn, should follow the same rules. In effect, this means that information can only flow downward - a parent can invoke a method, send data into or extract data from its child, but the child cannot forcibly do the same to its parent.
Think of what happens when you blow an air bubble underwater - you don't have to push the air towards the surface - you simply release it and it moves on its own. The same concept applies to event bubbling - deeper controls simply "release" their information - usually via an event - and it "floats" up the chain without directly invoking anything.
With regard to a website like Stackoverflow (or practically any kind of site), the concept of bubbling is the same. Obviously each individual post ought not directly put itself on the home page, but when a single post has been updated, that event is released from the deepest point in the hierarchy - a single post - and floats up to eventually the top level, where it is dealt with (choosing whether or not to display on the home page).
If you are asking about the term, I guess it is an analogy to an event 'bubbling' up to the top, like an air bubble does in liquid.
If you are asking what event bubbling is it is an event that is caught by one object that will refire it to any other objects that are listening to it.
To quote a good article here
... a technique called event bubbling
that allows a child control to
propagate events up its containment
hierarchy. Event bubbling enables
events to be raised from a more
convenient location in the controls
hierarchy and allows event handlers to
be attached to the original control as
well as to the control that exposes
the bubbled event.

Resources