Hello,
I have a weird behavior that sometimes occurs with my UltraTree embedded in a ButtonsRight of an UltraTestEditor.
Visually when I click on an item, another is selected however if I then use the keyboard's arrows the control move the selection as if it was the intended node that was selected.
After setting up some logs, I discovered that the control send two sets of BeforeSelect / AfterSelect events one after another, the first being the node I intended to select and the second ending up being the one the control consider selected.
The first stacktrace of the BeforeSelect event goes like this:
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo) à System.Environment.get_StackTrace() à WindowsLoadApplication.Controls.CustomerSelector.InternalTree_BeforeSelect(Object sender, BeforeSelectEventArgs e) dans c:\BI\QDT\WindowsLoadApplication\Controls\CustomerSelector.cs:ligne 139 à Infragistics.Win.UltraWinTree.UltraTree.OnBeforeSelect(BeforeSelectEventArgs e) à Infragistics.Win.UltraWinTree.UltraTree.FireEvent(TreeEventIds id, EventArgs e) à Infragistics.Win.UltraWinTree.UltraTree.SelectNewSelection(SelectedNodesCollection selected, Boolean isRangeSelect, Boolean invalidate) à Infragistics.Win.UltraWinTree.UltraTree.InternalSelectItem(ISelectableItem item, Boolean clearExistingSelection, Boolean select, Boolean invalidate) à Infragistics.Win.UltraWinTree.UltraTree.InternalSelectItem(ISelectableItem item, Boolean clearExistingSelection, Boolean select) à Infragistics.Win.UltraWinTree.UltraTree.Infragistics.Win.ISelectionManager.SelectItem(ISelectableItem item, Boolean clearExistingSelection) à Infragistics.Win.SelectionStrategySingle.OnMouseDown(ISelectableItem item, MouseMessageInfo& msginfo, Boolean forceDrag) à Infragistics.Win.SelectionStrategySingle.OnMouseDown(ISelectableItem item, MouseMessageInfo& msginfo) à Infragistics.Win.SelectionStrategySingle.OnMouseMessage(ISelectableItem item, MouseMessageInfo& msginfo) à Infragistics.Win.ControlUIElementBase.ProcessMouseDownHelper(Object sender, MouseEventArgs e) à Infragistics.Win.ControlUIElementBase.ProcessMouseDown(Object sender, MouseEventArgs e) à Infragistics.Win.Utilities.ProcessEvent(Control control, ProcessEvent eventToProcess, EventArgs e) à Infragistics.Win.UltraControlBase.OnMouseDown(MouseEventArgs e) à Infragistics.Win.UltraWinTree.UltraTree.OnMouseDown(MouseEventArgs e) à System.Windows.Forms.Control.WmMouseDown(Message& m, MouseButtons button, Int32 clicks) à System.Windows.Forms.Control.WndProc(Message& m) à System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) à System.Windows.Forms.NativeWindow.DefWndProc(Message& m) à Infragistics.Win.FormattedLinkLabel.FormattedLinkEditor.AccessibleTextManager.AccessibleTextSubclasser.WndProc(Message& msg) à System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) à System.Windows.Forms.NativeWindow.DefWndProc(Message& m) à Infragistics.Win.FormattedLinkLabel.IMENativeWindowManager.IMENativeWindow.WndProc(Message& m) à System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) à System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) à System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) à System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) à System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) à System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) à WindowsLoadApplication.Program.Main() dans c:\BI\QDT\WindowsLoadApplication\Program.cs:ligne 35 à System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) à System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData) à Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone() à System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) à System.Threading.ThreadHelper.ThreadStart()
The second stacktrace being:
à System.Environment.GetStackTrace(Exception e, Boolean needFileInfo) à System.Environment.get_StackTrace() à WindowsLoadApplication.Controls.CustomerSelector.InternalTree_BeforeSelect(Object sender, BeforeSelectEventArgs e) dans c:\BI\QDT\WindowsLoadApplication\Controls\CustomerSelector.cs:ligne 139 à Infragistics.Win.UltraWinTree.UltraTree.OnBeforeSelect(BeforeSelectEventArgs e) à Infragistics.Win.UltraWinTree.UltraTree.FireEvent(TreeEventIds id, EventArgs e) à Infragistics.Win.UltraWinTree.UltraTree.SelectNewSelection(SelectedNodesCollection selected, Boolean isRangeSelect, Boolean invalidate) à Infragistics.Win.UltraWinTree.UltraTree.InternalSelectItem(ISelectableItem item, Boolean clearExistingSelection, Boolean select, Boolean invalidate) à Infragistics.Win.UltraWinTree.UltraTree.InternalSelectItem(ISelectableItem item, Boolean clearExistingSelection, Boolean select) à Infragistics.Win.UltraWinTree.UltraTree.Infragistics.Win.ISelectionManager.SelectItem(ISelectableItem item, Boolean clearExistingSelection) à Infragistics.Win.SelectionStrategySingle.SelectItemAtPoint(Point point) à Infragistics.Win.SelectionStrategySingle.OnMouseMove(ISelectableItem item, MouseMessageInfo& msginfo) à Infragistics.Win.SelectionStrategySingle.OnMouseMessage(ISelectableItem item, MouseMessageInfo& msginfo) à Infragistics.Win.ControlUIElementBase.ProcessMouseMoveHelper(Object sender, MouseEventArgs e) à Infragistics.Win.ControlUIElementBase.ProcessMouseMove(Object sender, MouseEventArgs e) à Infragistics.Win.Utilities.ProcessEvent(Control control, ProcessEvent eventToProcess, EventArgs e) à Infragistics.Win.UltraControlBase.OnMouseMove(MouseEventArgs e) à Infragistics.Win.UltraWinTree.UltraTree.OnMouseMove(MouseEventArgs e) à System.Windows.Forms.Control.WmMouseMove(Message& m) à System.Windows.Forms.Control.WndProc(Message& m) à System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) à System.Windows.Forms.NativeWindow.DefWndProc(Message& m) à Infragistics.Win.FormattedLinkLabel.FormattedLinkEditor.AccessibleTextManager.AccessibleTextSubclasser.WndProc(Message& msg) à System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) à System.Windows.Forms.NativeWindow.DefWndProc(Message& m) à Infragistics.Win.FormattedLinkLabel.IMENativeWindowManager.IMENativeWindow.WndProc(Message& m) à System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) à System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) à System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) à System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) à System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) à System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) à WindowsLoadApplication.Program.Main() dans c:\BI\QDT\WindowsLoadApplication\Program.cs:ligne 35 à System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) à System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData) à Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone() à System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) à System.Threading.ThreadHelper.ThreadStart()
Judging by the second stacktrace, the superfluous event seems to be triggered by a mouse move action. If this resemble a behavior that can be deactivated I would like to know what option to change.
Thanks and regards.
Hi Eric,
The reason why a different node is selected when you click on an item is, you might be clicking on an item that is partially out of view when the dropdown is dropped down. Because of this both AfterSelect and BeforeSelect events are fired twice. Once when you click on a specific item and the second time when it selects the item in view when you scroll out of View.
Is there a specific reason why you are using BeforeSelect event. In your scenario I recommend using BeginInvoke. By calling BeginInvoke when selecting a node, you can avoid the other UI actions like scrolling out of view, mouse down or mouse move from modifying your selection. BeginInvoke executes the specified delegate asynchronously on the thread that the control's underlying handle was created on. You can read more about BeginInvoke here
https://msdn.microsoft.com/en-us/library/0b1bf3y3(v=vs.110).aspx
Please let me know if you have any questions.
Sincerely,
Sahaja Kokkalagadda
Associate Software Developer, Windows Forms
http://es.infragistics.com/
Hello Sahaja and thank you for your answer.
Unfortunately my scenario needs to use the BeforeSelect because of its ability to cancel the selection that is occurring.
Regarding the item visibility, if you take a look at the screenshot I added in attachment, you can see that it does not seems to hidden by anything (tooltip, ellipsis, etc.) aside from the cursor itself.
Note: I had to obfuscate my data for the screenshot with * instead of consonant but the control behave the same regardless.
Also I have noticed two things:
Of course I might mention that my events handler do not fiddle with the tree nodes' (not even browsing them). Sometimes if a requirement is met a MessageBox might appear but most of the time the selection is not canceled and I have yet to see the misbehavior happen when the MessageBox comes.
Thanks for your help.
I've yet to see this behavior in action. Attach your sample here so I can look at what is going on here. Thanks!