Focus on an EditCell in a ListView

It’s been longer than I hoped between blog postings – I’ve been tied up with putting in a new firewall and sorting out our fixed lines and mobiles – too many balls in the air at once at the moment to focus on the magical work of jscripts.

But an email came in to me whilst I was sleeping this morning – the question was “how do I set the focus on one of the editable cells within a ListView in the Init()?”

To be honest, I thought it wasn’t going to be possible – I’ve fought with the bubbling messaging mechanisms of the .Net framework before; projects I have the source code for and it’s been a nightmare, let alone something where I don’t control the raw code.

But I figured I’d give it a shot. After a couple of hours of trying I was writing a fairly long and detailed email explaining how I had failed miserably when I had an epiphany. It was almost like one of those dramatic House moments where someone says something which provides the association you need to solution the illness…errr…problem.

First things first…the program we are talking about is MWS422 and we want to set the focus on the “To loc” cell.

First things first, I wanted to determine what exactly the cell was – if it was simply a TextBox then it wouldn’t be too much of an issue, we could just issue a .Focus() against the TextBox when we got hold of the control. So, I wrote some code which iterated through each of the items in the first row of the ListView.

if(lvListView.Items.Count >= 1)
{
     var lviItem : ListRow = lvListView.Items[0];
     if(null != lviItem)
     {
        if(null != lviItem.Items)
        {
           // we need to determine the type of the object we are looking at, so we will check each time
           for(var i = 0; i < lviItem.Items.Length; i++)
           {
               MessageBox.Show(lviItem.Items[i].GetType());
           }
        }
     }
}

Ok, so now we now that we have an EditableCell I took at look in the Object Browser in Visual Studio to see if it was inherited from the TextBox control.

Sadly not, that would be way too easy. Interestingly I didn’t really see much of any help which would indicate what this control really is. Perhaps this overlays some control and they subscribe to the PropertyChanged event to determine when things should be changed?? Who knows…?

So, the next thing to do was just try calling .Focus() against the EditableCell and well, that didn’t work…

Which meant last restore…trawl through the object tree in Visual Studio to see if there was anything that could be related. As luck would have it, I started with the ListControl – I know that there are a lot of helper style functions with this object so…

I found these two entries – well actually, I found FocusFirstEditableCell() first and that appeared to set the focus to only the first row in the ListView, not quite enough for me. So with a little bit of playing I discovered that the FocusOnCell() would actually set the focus to the desired cell. FocusOnCell takes a variable called Name, and as luck would have it, the EditableCell has a property called Name.

So, the next thing I did was determine the Name of the cell in the fourth column. (well, actually I did this step after I discovered FocusFirstEditableCell() wouldn’t work and before I found out that FocusOnCell() would work but hey!)

if(lvListView.Items.Count >= 1)
{
     var lviItem : ListRow = lvListView.Items[0];
     if(null != lviItem)
     {
        if(null != lviItem.Items)
        {
           var ecEditableCell : EditableCell = lviItem.Items[3];
           // Display the name of the cell
           MessageBox.Show(ecEditableCell.Name);
        }
     }
}

I created a button which allowed me to test to ensure that the code was working and it was.

Now as I mentioned previously, I’ve had issues playing around with the focus of cells…and this took 7 iterations before I had the epiphany, all failed miserably, at best I could select the Row. It was complicated by having to copy the scripts to the server to test, we can’t just run it from the LSO jscript editor.

I tried subscribing to the changing of the selecteditem in the ListView as an example, but this didn’t work until it occurred to me, subscribe to the focus event on the ListView and fire our FocusOnCell() – and it worked! :-).

Anyways, code is below. Bear in mind that this is Proof of Concept, so if you loose focus and then reset the focus on the ListView the first row will be selected so you may want to modify a little.

import System;
import System.Windows;
import System.Windows.Controls;
import MForms;

import Mango.UI.Services.Lists;

package MForms.JScript
{
    class MWS422_SetFocusInListView_009
    {
        var gcController;
        var gbtnShowName : Button;      // this is the button that we will be adding
        var giChangeCount : int = 0;

        public function Init(element: Object, args: Object, controller : Object, debug : Object)
        {
            var content : Object = controller.RenderEngine.Content;
            var lvListView : ListView = controller.RenderEngine.ListControl.ListView;
            // TODO Add your code here
            gcController = controller;

            // add a button to the panel for testing
            gbtnShowName = new Button();
            gbtnShowName.Content = "Test Focus";
            Grid.SetColumnSpan(gbtnShowName, 15);
            Grid.SetColumn(gbtnShowName, 1);
            Grid.SetRow(gbtnShowName, 22);
            content.Children.Add(gbtnShowName);

            gbtnShowName.add_Click(OnShowNameClicked);

            lvListView.add_GotFocus(OnGotFocus);

            // this will set the focus to the first item in the listview
            controller.RenderEngine.ListControl.FocusFirstEditableCell();
            // this would set the focus to the cell called R1C4
            gcController.RenderEngine.ListControl.FocusOnCell("R1C4");


//            if(lvListView.Items.Count >= 1)
//            {
//                var lviItem : ListRow = lvListView.Items[0];//lvListView.ItemContainerGenerator.ContainerFromItem(lvListView.Items[0]);
//                if(null != lviItem)
//                {
//                    if(null != lviItem.Items)
//                    {
//                        // we need to determine the type of the object we are looking at, so we will check each time
//                        for(var i = 0; i < lviItem.Items.Length; i++)
//                        {
//                            MessageBox.Show(lviItem.Items[i].GetType());
//                        }
//                        // In my case, the cell we are looking at is in the forth column (I know from running the code above that it is an EditableCell)
//                        var ecEditableCell : EditableCell = lviItem.Items[3];
//                        // Display the name of the cell
//                        MessageBox.Show(ecEditableCell.Name);
//                    }
//                }
//            }
        }

        // this will actually do the setting of the focus
        function OnShowNameClicked(sender : Object, e : RoutedEventArgs)
        {
            // highlight the first item in the ListVIew
            gcController.RenderEngine.ListControl.FocusFirstEditableCell();
            // now set the focus on the specific EditableCell
            gcController.RenderEngine.ListControl.FocusOnCell("R1C4");
        }

        function OnGotFocus(sender : Object, e : RoutedEventArgs)
        {
            // highlight the first item in the ListVIew
            gcController.RenderEngine.ListControl.FocusFirstEditableCell();
            // now set the focus on the specific EditableCell
            gcController.RenderEngine.ListControl.FocusOnCell("R1C4");
        }

    }
}

Happy Coding!

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

9 Responses to Focus on an EditCell in a ListView

  1. Jean Monchery says:

    While try to copy a B Panel list view
    (var newItems = new String[row.Items.length];
    row.Items.CopyTo(newItems, 0) ) I got an error because the B Panel I was copying had editable cells. How can I get the CopyTo method to work with editable cells?

  2. potatoit says:

    Hi Jean,
    you’ll probably need to manually loop through copy each entry in the array rather than using the CopyTo method.

    Cheers,
    Scott

  3. Priyantha says:

    How can I readonly m3 listview column.. program name is m3 supplier invoice and column name is Inv Qty . please help me.

    • potatoit says:

      Hi Priyantha,

      specifically which program? APS100? What panel?

      Depending on the program you can set the security so the users can only go in to Display mode.

      There are a variety of methods – you may be able to cancel any changes that a user makes, you may be able to determine the column and then loop through the lines and set the TextBox in the ListView to read only.
      It really depends on the details of what you want to achieve and which program.

      Cheers,
      Scott

  4. Priyantha says:

    dear Scott,

    Program name is APS360 Panel Name : B Column Name is Inv Qty.

    I want to readonly Inv Qty column .

    I have tryed following codes

    InstanceController con = (InstanceController)controller;
    Object content = con.RenderEngine.Content;

    // TODO Add your code here
    MForms.ListControl listControl = con.RenderEngine.ListControl;
    System.Windows.Controls.ListView listView = con.RenderEngine.ListViewControl;

    ItemCollection rows = null;
    rows = listView.Items;
    foreach (var item in rows)
    {
    int column1 = listControl.GetColumnIndexByName(“IVQA”);
    EditableCell cell = item as EditableCell;
    }

    but there is no any property to readonly cell . I want to readonly entire column. i tryed it with Snoop 2.8.0 . it is showed it as a Textbox . but i unable to access it using tree hirarchy . please help me .

    Thank you
    Priyantha

  5. Dulan says:

    Hi Scott,
    Is there a way to disable these editable fields

    I have tested below options, but they are not working
    Disable=true;
    IsReadOnly = false;
    CanEdit= false;

    Regards
    Dulan

    • potatoit says:

      Hi Dulan,

      if you want to specifically disable one of the entries, you’ll need to convert the code that I posted a link to in the previous comment in to JScript. This will is not a very nice way to do it.

      Or, you can intercept the Requesting event to cancel any changes.

      Cheers,
      Scott

      • priyantha says:

        Shall we stop focus on particular cell using OnGotFocus event. We can check condition and stop focus on it.

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