Keep Business Process Display State as collapsed - dynamics-crm

I am trying to keep the business process flow display state as collapsed.
I am currently making it collapsed at addOnStageChange
Xrm.Page.ui.process.setDisplayState('collapsed');
It works fine on Stage Change for me. But if I click on the same stage twice which means stage is not changing then the BPF gets expanded. I am assuming if it is the default behavior.
How can I prevent it from expanding permanently?

If you are using Unified Interface it will be collapsed by defualt.
But if you are using legacy web client.
Add onload event on your From (for ex.Opportunity entity) and add below lines of code.
function collapseOpporBusinessProcess(){setTimeout(collapseOpporBusinessProcessDelay,300)}
function collapseOpporBusinessProcessDelay(){Xrm.Page.ui.process!=null&&Xrm.Page.ui.process.setDisplayState(“collapsed”)}

BPF cannot be collapsed always in classic UI, but possible in UCI like popout behavior or flyout without expanding. It needs some unsupported DOM manipulation in classic UI to nullify the click event of stage chevron or simply user training not to click it at all. Or better create a similar UI using webresource if you want.
It fails the original purpose, and re-purposing the BPF raise these kind of questions. If you have built the necessary business logic already in some other means - then custom UI is better choice rather than bending the BPF.
BPF is for guided process advancement, we can add attributes/entities as steps to move forward and enforce the field value requirements for reaching next level. I know some clients use them as tabs, some use them as just chevron tracker, so they don't want to waste the real estate under the BPF as they don't need any fields under the stages.

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.

Talking Among GWT Panels using UIBinder Layout

New to GWT here...
I'm using the UIBinder approach to layout an app, somewhat in the style of the GWT Mail sample. The app starts with a DockLayoutPanel added to RootLayoutPanel within the onModuleLoad() method. The DockLayoutPanel has a static North and a static South, using a custom center widget defined like:
public class BigLayoutWidget extends ResizeComposite {
...
}
This custom widget is laid out using BigLayoutWidget.ui.xml, which in turn consists of a TabLayoutPanel (3 tabs), the first of which contains a SplitLayoutPanel divided into WEST (Shortcuts.ui.xml) and CENTER (Workpanel.ui.xml). Shortcuts, in turn, consists of a StackLayoutPanel with 3 stacks, each defined in its own ui.xml file.
I want click events within one of Shortcuts' individual stacks to change the contents of Workpanel, but so far I've only been able to manipulate widgets within the same class. Using the simplest case, I can't get a button click w/in Shortcuts to clear the contents of Workpanel or make WorkPanel non-visible.
A few questions...
Is ResizeComposite the right type of class to extend for this? I'm following the approach from the Mail example for TopPanel, MailList, etc, so maybe not?
How can I make these clicks manipulate the contents of panels in which they do NOT reside?
Are listeners no longer recommended for handling events? I thought I saw somewhere during compilation that ClickHandlers are used these days, and the click listener "subscription" approach is being deprecated (I'm mostly using #UiHandler annotations)
Is there an easy way to get a handle to specific elements in my app/page? (Applying the "ID" field in the UI.XML file generates a deprecation warning). I'm looking for something like a document.getElementById() that get me a handle to specific elements. If that exists, how do I set the handle/ID on the element, and how can I then call that element by name/id?
Note that I have the layout itself pretty well nailed; it's the interaction from one ui.xml modularized panel to the next that I can't quite get.
Thanks in advance.
If you don't have a use for resizing events than just use Composite
What you want is what the GWT devs called message bus (implemented as HandlerManager). You can get a nice explanation in the widely discussed (for example, on the GWT Google Group, just search for 'mvp') presentation by Ray Ryan from Google I/O 2009 which can be found here. Basically, you "broadcast" an event on that message bus and then a Widget listening for that event gets the message and does its stuff.
Yep, *Handlers are the current way of handling events - the usage is basically the same so migration shouldn't be a problem (docs). They changed it so that they could introduce custom fields in the future, without breaking existing code.
If you've set an id for any DOM element (for Widgets I use someWidget.getElement().setId(id), usually in combination with DOM.createUniqueId()) you can get it via GWT.get(String id). You'll get then a RootPanel which you'll have to cast to the right Widget class - as you can see it can get a little 'hackish' (what if you change the type of the Widget by that id? Exceptions, or worse), so I'd recommend sticking with MVP (see the first point) and communicating via the message bus. Remember however, that sometimes it's also good to aggregate - not everything has to be handled via the message bus :)
Bottom line is I'd recommend embracing MVP (and History) as soon as possible - it makes GWT development much easier and less messy :) (I know from experience, that with time the code starts to look like a nightmare, if you don't divide it into presentation, view, etc.)

What are some good ways of managing settings in gui applications?

If I have a setting that is accessible via a menu item or configuration window that can change at runtime, for example "bold text on/off"; what are some good ways of ensuring that all applicable components are aware the value of this setting?
You didn't provide specifics of an implementation language, so the asnwer will be somewhat generic.
Assuming your GUI is in a language which supports even model (e.g. Java), simply have an event handler for any component which should be affected by settings and which gets triggered on an event "setting changed". Then call such event from the setting config window. Don't forget to redraw when all components are done updating (ore redraw as each component is updated).
An additional point is to hopefully have generic sub-components used.
As an example, if you are using label text with a certain font which is configurable, then use a common "label with configurable font" class which ensures you never need to assign the above event listener to every label you create.
If there will be a lot of setting I have implemented a sqlite DB to hold the changes for smaller amount of changes key value pair in a file is good enough. Then implement a observer design pattern so when any changes are done a list of gui classes are called to do the change.

Distinguish between designer and runtime code

I have two processes which exange messages each other.
Process A is a normal (i.e non-qt) program which sends messages to process B.
Process B is a QT GUI application showing received messages into a text box.
I created a customized widget (called ShowMessages) which inherits from QPlainTextEdit and reads messages from a pipe when a timer expires, and appends them in the text box.
Code is not really designed like this (which would be pretty bad design I think), but it's just to make things simple here.
For reasons I won't tell, process A cannot be shut down while I'm creating the form using qt-designer.
Problem is that while I'm using qt designer (thus selecting the ShowMessages widget and putting it within the window) the widget begins to show messages, even if I'm in the designer. This feature is cool but the problem is that when I save the form, already present messages are saved in .ui file, which results in turn in bad behaviour when I start process B (because process starts showing messages I received during the creation phase).
I could clean the text box just after process B starts, but I think that avoiding messages to be present in the .ui file is much better. What I want is to be able to write code like this for the widget:
if <I'm not in the designer>
timer = QtCore.QTimer(self)
QtCore.QObject.connect(timer, QtCore.SIGNAL("timeout()"), self, QtCore.SLOT("on_timer()"));
timer.start(2000)
Is there an qt function to know if I'm in the designer? Do you think that distinguishing between designer and runtime code is "bad"?
(Sorry for mistakes, but English is not my primary language)
Maybe your widget should have a flag for whether it's "active" and default it to False so while you're in the designer, it doesn't do anything at all. In code you would set it to active when you want to see the messages. Then you also have the ability to turn it off in other scenarios as well.
But I have to say, it sounds like you're putting "controller" code into a "view" widget which can and probably will spell trouble for you down the road (including the current Qt designer problem you're having now).
Consider reading up on the MVC (model-view-controller) design pattern, if you haven't already.
Update:
To be fair, your question did ask how to detect whether you're in designer :)
http://doc.trolltech.com/4.3/designer-creating-custom-widgets.html#creating-well-behaved-widgets
To give custom widgets special
behavior in Qt Designer, provide an
implementation of the initialize()
function to configure the widget
construction process for Qt Designer
specific behavior. This function will
be called for the first time before
any calls to createWidget() and could
perhaps set an internal flag that can
be tested later when Qt Designer calls
the plugin's createWidget() function.
According to the doc, you basically could set your "inDesignerFlag" to true in the initialize() function of your widget. Then detect that flag where required in your widget's code.

Resources