locked
DataGrid LoadingRow does not fire when application first opened and within tab RRS feed

  • Question

  • I have a List & Details screen. One datagrid with the parent records, and two child grids with child records. The child grids are arranged in tabs as per the default layout when using a list and details screen.

    I've noticed that the LoadingRow event of a child DataGrid, which is not visible upon opening the screen, does not fire consistently until the child DataGrid in question has been activated and a new parent selected. After that it works just fine.

    Here is the behavior

    As you can see when the second grid is rendered, only the new row is colored red.

    But once a new parent record is selected, all is good again.

    here is the code for that screen

      public partial class PeopleSetListDetail
        {
            partial void PeopleSetListDetail_InitializeDataWorkspace(List<IDataService> saveChangesTo)
            {
                // Write your code here.
                this.FindControl("AnimalsCollection").ControlAvailable += PeopleSetListDetail_ControlAvailable;
                this.FindControl("BooksCollection").ControlAvailable +=PeopleSetListDetail_ControlAvailable;
            }
    
            void PeopleSetListDetail_ControlAvailable(object sender, ControlAvailableEventArgs e)
            {
                ((DataGrid)e.Control).LoadingRow += PeopleSetListDetail_LoadingRow;
            }
    
            void PeopleSetListDetail_LoadingRow(object sender, DataGridRowEventArgs e)
            {
                e.Row.Background = new SolidColorBrush(Colors.Red);
            }
        }

    Is it a bug ?

    Anyone got any suggestions on a workaround ? While the above example is just to illustrate the behavior, I've another app which I relies on the LoadingRow working as soon as the grid is rendered.

    Thanks

    Friday, February 14, 2014 1:03 PM

Answers

  • Thanks for the ideas Josh, 

    I un ticked the "Auto Execute Query", and then wired up a simple button to call the Load() method on the collection as a test.

    When the grid is displayed it is empty, but when I kick the load method all of the rows render and execute LowdingRow method.

    Keeping the "Auto Execute Query" unticked isnt a workable solution. One would have to wire in a whole bunch of other plumbing to maintain a similar behavior to which a checked "Auto Execute Query" provides.

    So it appears that i'm possibly not early enough. But I cant see how to get in any earlier. Per my code in the 1st post, The method handler for the ControlAvailable event is added in the InitializeDataWorkspace screen event,  which from what I can determine, is the earliest screen event.

    While it is a hack, I've added the following code as a workaround.

    bool BooksCollectionNowAvailable = false;
            void PeopleSetListDetail_ControlAvailable(object sender, ControlAvailableEventArgs e)
            {
                DataGrid d = (DataGrid)e.Control;
                if(d.Name == "BooksCollection" & !this.BooksCollectionNowAvailable)
                {
                    d.OnApplyTemplate();
                    this.BooksCollectionNowAvailable = true;
                }
                ((DataGrid)e.Control).LoadingRow += PeopleSetListDetail_LoadingRow;
            }
    The OnApplyTempate() method causes the grid to re display its children controls. When that happens the all the LoadingRow events fire! The OnApplyTemplate() only needs to be called the very first time the grid is visible. After that it behaves itself.
     
    • Marked as answer by Angie Xu Monday, February 24, 2014 1:28 AM
    Friday, February 21, 2014 9:08 AM

All replies

  • Look like a bug. 

    Is the grid a tab item in the designer (directly under the tabs layout)?  If so, perhaps try placing a group as the tab item then the grid within that group.  Like this (off topic, but illustrates suggestion):

    http://social.msdn.microsoft.com/Forums/vstudio/en-US/6eb3da46-1813-4540-bc20-8fcaec71849a/tab-name-always-the-same-as-datagrid-header?forum=lightswitch

    Just curious if doing this would change the timing of controlavailable, etc.

    HTH,

    Josh

    Friday, February 14, 2014 2:56 PM
  • Happy to try any suggestions. 

    Nesting the Grid in a group did not have any effect. 

    Keep em coming.

    Friday, February 14, 2014 9:43 PM
  • Move your event handlers from InitializeDataWorkspace to the screen Created method and it should work.  What I believe is happening is that you are calling FindControl before the control has finished loading.  The screen Created method will fix that.
    Friday, February 14, 2014 10:32 PM
  • Just moved the code, no good, Problem still exists...

    Friday, February 14, 2014 10:48 PM
  • Sorry to hear that you're still having trouble.  I would have thought moving the code would have helped.  Did you clean, rebuild all, etc?
    • Edited by Hessc Saturday, February 15, 2014 2:26 AM
    Saturday, February 15, 2014 2:26 AM
  • Yeah, did that. 

    I Just tried another test. I added lots of records to the datatable which the problematic grid binds to. When I click the tab the all the rows are white (except the add new row row) on the first page, but if I click to go to the next page, all the rows now become red and all is good again.  So this is an analogous to clicking on a new parent.

    So it seems as soon as the datagrid becomes visible and it has to regenerate its rows its behavior returns to normal.

    Saturday, February 15, 2014 2:59 AM
  • Perhaps the initial rows are loaded before ControlAvailable fires so the LoadingRow handler doesn't fire for the first page of rows.(?)

    I've done formatting such as this with SetBinding which doesn't have this problem, but I understand that won't work due to requirements of your other app.

    Maybe try unchecking Auto Execute Query in the properties pane of the BooksCollection query in screen designer(?)

    HTH,

    Josh


    • Edited by joshbooker Tuesday, February 18, 2014 12:34 AM
    Tuesday, February 18, 2014 12:33 AM
  • Thanks for the ideas Josh, 

    I un ticked the "Auto Execute Query", and then wired up a simple button to call the Load() method on the collection as a test.

    When the grid is displayed it is empty, but when I kick the load method all of the rows render and execute LowdingRow method.

    Keeping the "Auto Execute Query" unticked isnt a workable solution. One would have to wire in a whole bunch of other plumbing to maintain a similar behavior to which a checked "Auto Execute Query" provides.

    So it appears that i'm possibly not early enough. But I cant see how to get in any earlier. Per my code in the 1st post, The method handler for the ControlAvailable event is added in the InitializeDataWorkspace screen event,  which from what I can determine, is the earliest screen event.

    While it is a hack, I've added the following code as a workaround.

    bool BooksCollectionNowAvailable = false;
            void PeopleSetListDetail_ControlAvailable(object sender, ControlAvailableEventArgs e)
            {
                DataGrid d = (DataGrid)e.Control;
                if(d.Name == "BooksCollection" & !this.BooksCollectionNowAvailable)
                {
                    d.OnApplyTemplate();
                    this.BooksCollectionNowAvailable = true;
                }
                ((DataGrid)e.Control).LoadingRow += PeopleSetListDetail_LoadingRow;
            }
    The OnApplyTempate() method causes the grid to re display its children controls. When that happens the all the LoadingRow events fire! The OnApplyTemplate() only needs to be called the very first time the grid is visible. After that it behaves itself.
     
    • Marked as answer by Angie Xu Monday, February 24, 2014 1:28 AM
    Friday, February 21, 2014 9:08 AM
  • Glad it's working for you.  Doesn't look too hacky, in my view.  I still think it's the ControlAvailable which is too late.  Even though LS recommends using controlavailable to avoid being too early, I wonder if you can directly handle the Loaded event of the grid without using controlavailable. 

    Here is something that I think may apply:  Control Lifecycle.  Would be nice to get such a chart which is LS specific.  Another nice read:  Loaded Event Timing

    Still, your solution is a nice one.  Post the complete code in your other thread re: enabling grid button control. 

    Josh

    Friday, February 21, 2014 2:29 PM
  • Hi, i had the exact same problem (using the screen Created Method though), this was very helpfull and solved it, thanks!
    Thursday, April 24, 2014 12:15 PM