Where Did My Control Go?

Update 2011/01/02 – if you read the comments below, you’ll note that Al mentions that the issue where Init() isn’t called when the Sorting Order / Inquiry Type changes I am talking about here doesn’t occur when you publish the code – it appears to only be when you are testing in the Script Tool! :-[

So, Smart Office rocks! The Jscript functionality is awesome. But…

You add a control to a B panel, and then change the “Sorting Order” and your control disappears – somewhat irritating.

This is a challenge that I recently came across and still don’t have a nice solution, I have yet to find an event that I can subscribe to that allows me to redraw my controls.

Lawson Smart Office does some nifty stuff, when you change the Sorting Order the controls that sit below the Sort Order ComboBox are removed and destroyed, and then the new controls associated with the new Sorting Order are added – any events that you had tied to those controls is now invalid.

However, the Init() method isn’t called again so your controls don’t get added.

I have a little script which illustrates this with Dialog Boxes. The script was used against OIS300. We have subscribed to the Sorting Order ComboBox SelectChanged event and the unload even of the ListView (I only did one control to illustrate what was happening).

Getting to the Sort Order ComboBox is a little bit of a challenge aswell, we can’t find it with the ScriptUtil.FindChild() so we have to do it the hard way, and that is walk up the tree and then walk down the visual tree until we find WWQTTP – the Sort Order ComboBox.

In this script the following will happen

  1. Change Sorting Order
  2. Event: ListView unloaded
  3. Event: ComboBox Selection Changed -1
  4. Event: ComboBox Selection Changed -1
  5. Event: ComboBox Selection Changed new selection
  6. Event: ComboBox Selection Changed new selection
  7. Controls are re-added (no event added for this)

The ListView event will only fire once, because the we subscribed to the ListView Unloaded event and that ListView no-longer exists.

import System;
import System.Windows;
import System.Windows.Controls;
import System.Windows.Media;
import System.Windows.Media.Media3D;
import MForms;

package MForms.JScript
{
   class Sample
   {
           var gController;
           var gContent;
           var gDebug;
           var grdLVParent : Grid;
           var glvListView : ListView;
           var gbtnPickButton : Button;
           var gcmbSortOption : ComboBox;

      public function Init(element: Object, args: Object, controller : Object, debug : Object)
      {
              gController = controller;
              gDebug = debug;

            var content : Object = controller.RenderEngine.Content;
            gContent = content;

            var lcListControl : ListControl = controller.RenderEngine.ListControl;

            glvListView  = lcListControl.ListView;

            grdLVParent = glvListView.Parent;

            grdLVParent.add_Unloaded(OnGridUnloaded);

            glvListView.add_Unloaded(OnListViewUnloaded);

            goUp();

            if(null != gcmbSortOption)
            {
                gcmbSortOption.add_SelectionChanged(onComboBoxSelectionChanged)
            }
      }

          public function OnListViewUnloaded(sender : Object, e : RoutedEventArgs)
        {
            MessageBox.Show("ListView Unloaded");
        }

          public function OnGridUnloaded(sender : Object, e : RoutedEventArgs)
        {
            MessageBox.Show("Grid Unloaded");
        }

        public function onComboBoxSelectionChanged(sender : Object, e : SelectionChangedEventArgs)
        {
            MessageBox.Show("ComboBox Selection Changed" + gcmbSortOption.SelectedIndex);
        }

      private function findComboBox(parent : Object, depth : int, debug : Object)
      {
            try
            {
                if(null != parent)
                {
                    // get the type of our object, we do this
                    // so we can check if the object inherits
                    // from a DependencyObject
                    var parentobjType : Type = parent.GetType();
                    if(parentobjType.IsSubclassOf(DependencyObject) == true)
                    {
                        // loop through the children of this object
                        for(var i=0; i < VisualTreeHelper.GetChildrenCount(parent);i++)                         {                             // retrieve the child object                             var current : Object = VisualTreeHelper.GetChild(parent,i);                             if(null != current)                             {                                 // here we shall deterine the type of the new object                                 var objType = current.GetType();                                                                  if(null != objType)                                 {                                     // we're looking for the Name property, because                                     // this is what I am interested in                                     var objPropertyName = objType.GetProperty("Name");                                     if(null != objPropertyName)                                     {                                         var strName = objPropertyName.GetValue(current);                                         if(null != strName)                                         {                                           if(0 == String.Compare(strName,"WWQTTP"))                                           {                                                 gcmbSortOption = current;                                                 break;                                           }                                                                                          // does the current object have any children?                                           if(VisualTreeHelper.GetChildrenCount(current) >= 1)
                                          {
                                                // recurse down
                                                findComboBox(current, depth+1, debug);
                                                }
                                            }
                                        }
                                    }
                                }
                       }
                    }
                }
            }
            catch(ex)
            {
                debug.WriteLine("!-! Exception: " + ex.Message + " " + ex.StackTrace);
            }
      }

        private function goUp()
        {
           var parent : Object = gContent;
           var lastParent : Object = gContent;

           // here we will loop UP the VisualTree seeking the top
           while(null != (parent = VisualTreeHelper.GetParent(parent)))
           {
               lastParent = parent;

               var objType = lastParent.GetType();
               var objPropertyName = objType.GetProperty("Name");
               var strName : String = objPropertyName.GetValue(lastParent)

               if(null != strName)
               {
                   if(String.Compare(strName,"ContainerPanel") == 0)
                   {
                       for(var i : int = 0; i < lastParent.Children.Count; i++)
                       {
                           var con = findComboBox(lastParent);
                           if(null != con)
                           {
                               MessageBox.Show("xxFound!");
                           }
                           break;
                       }

                       break;
                   }
               }

           }
        }
   }
}

This entry was posted in Development, M3 / MoveX. Bookmark the permalink.

2 Responses to Where Did My Control Go?

  1. Al says:

    Hi Scott.

    That does sound strange. I’ve a script attached to PMS100/B under 7.1 Smart Client. I can change the Sorting Order and the controls I’ve added (a button and a text box) remain.

    Certainly while you’re developing the jscript Init() will not be called again, but once it is published and attached to the screen, as far as I can tell Init() should be called again when you change the sorting order.

    Al.

    • potatoit says:

      Hi Al,

      well, I’ll be, once published – even publishing locally using the registry entry – Init() does get called when the Sorting Order / Inquiry type changes. One of the idiosyncrasies of Smart [Client | Office] I guess.

      I’ll have to keep that in mind when testing.

      Thanks for that Al, guess I better update the CASE that I have open 🙂

      Cheers,
      Scott

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s