none
Custom Shell - Auto selecting the correct screen tab when closing a screen

    Question

  • The walkthrough on creating your own Shell sucks... http://msdn.microsoft.com/en-us/library/hh290138.aspx

    I have now spent more hours than I care to bitch about hitting problem, after problem after problem. Originally I wanted something almost identical to the default LS Shell with a few minor tweaks (and I'm sure other users would like this also). The walkthrough might look like the default Shell but it acts nothing like it.

    The things I have had to solve so far (to mention but a few) are...

    Get default screen to auto load
    Rip the Double click timer code nonsense to open a screen with a single click
    If a Navigation screen is clicked and the tab is already opened auto navigate to existing tab and display screen
    Cope with the above if "Allow Multiple Instances" of said screen has been checked within the LS app (and work like the default Shell) <- That was real fun.

    I am now stuck on...
    If a tab is being closed - Auto switch to correct tab so any associated dialog (if a screen is flagged as dirty) is displayed.
    Any ideas anyone please? 

    I can't see why MS can't publish the Default LightSwitch Shell code and save us all heartache? LS is a fantastic product if you want to build quick Biz apps but if you want to customise the look and feel it's a nightmare trying to get the default shells functionality with the Walkthrough that is published. 

    Paul.

    Ps. I haven't got to validation yet (which I would also like to act identical to the default Shell) so I'm looking forward to wasting more time on that one. 

    Website design for £249, Unlimited pages, Facebook and Twitter integration. www.domainscanners.com

    Tuesday, March 06, 2012 12:38 AM

Answers

  • I need to test this a bit more but I think I have solved this by setting up a notification...

    this.ServiceProxy.NotificationService.Subscribe(typeof(ScreenActivateNotification), this.OnScreenActivated);

    and the method...

            public void OnScreenActivated(Notification n)
            {
                ScreenActivateNotification screenActivateNotification = (ScreenActivateNotification)n;
                IScreenObject screenObject = screenActivateNotification.Screen;

                foreach (TabItem ti in this.ScreenArea.Items)
                {
                    IScreenObject realScreenObject = ((MyScreenObject)ti.DataContext).RealScreenObject;

                    if (realScreenObject == screenObject)
                    {
                        this.ScreenArea.SelectedItem = ti;
                        this.ServiceProxy.ActiveScreensViewModel.Current = ((MyScreenObject)(ti.DataContext)).RealScreenObject;
                        break;
                    }
                }
            }



    Website design for £249, Unlimited pages, Facebook and Twitter integration. www.domainscanners.com

    Tuesday, March 06, 2012 6:25 PM

All replies

  • I need to test this a bit more but I think I have solved this by setting up a notification...

    this.ServiceProxy.NotificationService.Subscribe(typeof(ScreenActivateNotification), this.OnScreenActivated);

    and the method...

            public void OnScreenActivated(Notification n)
            {
                ScreenActivateNotification screenActivateNotification = (ScreenActivateNotification)n;
                IScreenObject screenObject = screenActivateNotification.Screen;

                foreach (TabItem ti in this.ScreenArea.Items)
                {
                    IScreenObject realScreenObject = ((MyScreenObject)ti.DataContext).RealScreenObject;

                    if (realScreenObject == screenObject)
                    {
                        this.ScreenArea.SelectedItem = ti;
                        this.ServiceProxy.ActiveScreensViewModel.Current = ((MyScreenObject)(ti.DataContext)).RealScreenObject;
                        break;
                    }
                }
            }



    Website design for £249, Unlimited pages, Facebook and Twitter integration. www.domainscanners.com

    Tuesday, March 06, 2012 6:25 PM
  • hi!

    in walktrough this sub closes current tab and activates next:

    Public Sub OnScreenClosed(n As Notification)
                ' A screen has been closed and therefore removed from the application's
                ' collection of active screens.  In response to this, we need to do
                ' two things:
                '  1.  Remove the tab item that was displaying this screen.
                '  2.  Set the "current" screen to the screen that will be displayed
                '      in the tab item that will be made active.
                Dim screenClosedNotification As ScreenClosedNotification = n
                Dim screenObject As IScreenObject = screenClosedNotification.Screen
    
                For Each ti As TabItem In Me.ScreenArea.Items
                    ' We need to get the real IScreenObject from the instance of the MyScreenObject.
                    Dim realScreenObject As IScreenObject = CType(ti.DataContext, MyScreenObject).RealScreenObject
    
                    If realScreenObject Is screenObject Then
                        Me.ScreenArea.Items.Remove(ti)
                        Exit For
                    End If
                Next
    
                ' If there are any tab items left, set the current tab to the last one in the list
                ' AND set the current screen to be the screen contained within that tab item.
                Dim count As Integer = Me.ScreenArea.Items.Count
    
                If count > 0 Then
                    Dim ti As TabItem = Me.ScreenArea.Items(count - 1)
    
                    Me.ScreenArea.SelectedItem = ti
                    Me.ServiceProxy.ActiveScreensViewModel.Current = CType(ti.DataContext, MyScreenObject).RealScreenObject
                End If
            End Sub
    
           

    hth..

    Kivito


    Nobody expects the Spanish Inquisition! (M.P.F.C.)



    • Edited by Kivito Wednesday, March 07, 2012 8:15 AM
    Wednesday, March 07, 2012 8:14 AM
  • Hi Kivito,

    The walkthrough code above does not handle a dirty screen that requires saving as per the last point of my original rant. 

    If anyone has attempted to build a custom shell via the Walkthrough it quickly becomes apparent that it behaves nothing like the Standard shell. Looking around only a handful of shells have been built and most (if not all) lack the functionality of the standard shell. I now understand why as I am in my second week working full time on my own shell and trying to implement the standard shell's functionality is proving difficult. Of course, it probably wasn't that difficult for whoever built the standard shell as they worked on or close to the LightSwitch team and had everything to hand. I have pretty much been working in the dark on this and cant help but be frustrated. Although many people have asked for the standard shell code to be published Microsoft have refused to even give reason as to why they wont publish.

    Paul. 


    Website design for £249, Unlimited pages, Facebook and Twitter integration. www.domainscanners.com


    • Edited by Hale Wednesday, March 07, 2012 11:21 AM
    Wednesday, March 07, 2012 11:19 AM
  • hi Paul!

    i followed same tutorial and if i have dirty screen, it asks me if i want to save changes when i click close button on tab, and also there is star that shows if screen is dirty.. as i see there is class MyScreenObject and inside is "IsDirty" property on which you can bind to show "star" on tab header.. as i understand if screen is dirty, "MyScreenObject" will ask you what you want to do before it sends notification to close the screen (like code above).. but you are right about tutorials, im not the biggest brain in neighborhood and im also having struggle with creating useful shell, it would be great to have more tutorials on this, not "just one" article (ok, Michael Washington and other guys made few great tutorials, but you know what i mean)..

    Kivito


    Nobody expects the Spanish Inquisition! (M.P.F.C.)


    • Edited by Kivito Wednesday, March 07, 2012 9:19 PM
    Wednesday, March 07, 2012 9:17 PM
  • You may wish to have a look at DockShell. It wraps 3rd party ribbon and docking controls using a provider based approach. It use MEF to locate these controls and then surfaces LightSwitch Navigation and Screens using those 3rd party controls.

    Johnny Larue

    Sunday, March 11, 2012 5:48 PM
  • Ps. I haven't got to validation yet (which I would also like to act identical to the default Shell) so I'm looking forward to wasting more time on that one. 

    Do you ever get the default validation working in the custom shell exactly like the default Shell?

    Friday, October 19, 2012 10:48 PM
  • I did - eventually. If memory serves me right a kind chap off the LS team gave me some pointers. The trick was using a ValidationSummary Control on each screen as opposed to having a single control. To design the complete shell took almost 2 months! Very much hoping things get simpler in the future. You can check out the shell at http://LightSwitchShells.com

    Paul.


    LightSwitchShells.com - Make your business apps shine! Website design for £249, Unlimited pages, Facebook and Twitter integration. www.domainscanners.com

    Tuesday, October 23, 2012 12:38 PM
  • Yes agree, the shell walk-through is rather weak in documentation. 

    Within our Shell (DockShell) we create a series of distinct containment scenarios to host each LS screen with as many backing view models to manage and track properties such as IsDirty.

    Our shell also took many, many months to develop and perfect mostly due to the fact that we utilized an IOC pattern to wrap third party controls for each area of functional concern required within the shell as well we built a DSL modeling tool to simplify it's configuration in C# or VB.Net.

    We provide a separate view container per each LS Screen that you can customize in which you can include the Validation Summary Control which can be easily bound to  backing properties exposed through supporting ViewModels.

    I don't think there is a straight up answer to your question as it depends greatly on your discrete components within your overall shell design. 

    Hope this was somewhat helpful!

    Johnny

    Thursday, November 01, 2012 11:23 AM