none
Styling commands on custom collection control RRS feed

  • Question

  • Hey experts,

    I'm building a custom LS Collection control.  To display the commands (add, edit, delete) I've added a CommandGroupPresenter as per the Cosmo sources:

            <framework:CommandGroupPresenter 
                                        x:Name="CommandGroupPresenterElement"  
                                        Commands="{Binding ContentItem.CommandItems}" 
                                        HorizontalAlignment="Left" 
                                        VerticalAlignment="Bottom" 
                                        Margin="3,5,3,8" 
                                        TabIndex="1" 
                                        ContainerState="IntegratedCommandGroup" 
                                        />

    This works like a charm, only the commands are 'styled' as simple gray buttons instead of nifty little icons.  

    

    I can't really find where this styling could be done, any help would be appreciated.


    Thanks,

    Jan


    It's your story - time to switch on the innovation.||About me||LightSwitch blog

    Monday, October 21, 2013 11:29 AM

Answers

  • Instead of using code to hide the commands that are automatically shown, specify that the CommandItemsSupport property on your Control definition in the LSML file is set to CustomDisplay. This means that the control will handle showing commands itself rather than letting the LightSwitch runtime show them.

    Justin Anderson, LightSwitch Development Team

    Monday, November 4, 2013 2:28 AM
    Moderator
  • Found it...

    For those LS hackers among you, here's the 1-2-3 for future reference.

    a) To hide the default gray command buttons that are placed underneath your user control by default, add an event handler to your control's Loaded event, then walk up the visual tree to find the grid that holds both your control and the automagically added gray command buttons, and hide them.

            void MyUserControl_Loaded(object sender, RoutedEventArgs e)
            {
                //find Microsoft.LightSwitch.Presentation.Framework.AutoCommandGroupPresenterGrid
                Grid host = FindUpVisualTree<Grid>(this); 
                //hide default controls
                host.Children[1].Visibility = System.Windows.Visibility.Collapsed; 
            }
    
            // walk up the visual tree to find object of type T, starting from initial object
            // Modified from http://www.codeproject.com/Tips/75816/Walk-up-the-Visual-Tree
            public static T FindUpVisualTree<T>(DependencyObject initial) where T : DependencyObject
            {
                DependencyObject current = initial;
    
                while (current != null && !typeof(T).IsAssignableFrom(current.GetType()))
                {
                    current = VisualTreeHelper.GetParent(current);
                }
                return current as T;
            }


    b) To add the command buttons in a place where you want them, simply add a "CommandGroupPresenter" where you need one.

    Reference:

        xmlns:framework="clr-namespace:Microsoft.LightSwitch.Presentation.Framework;assembly=Microsoft.LightSwitch.Client"

    Code:

                <framework:CommandGroupPresenter 
                                        x:Name="CommandGroupPresenterElement"   
                                        Commands="{Binding ContentItem.CommandItems}" 
                                        HorizontalAlignment="Left" 
                                        VerticalAlignment="Bottom" 
                                        HorizontalContentAlignment="Left"
                                        Margin="3,5,3,8" 
                                        TabIndex="1" 
                                        ContainerState="IntegratedCommandGroup" 
                                        Loaded="CommandGroupPresenterElement_Loaded"
                                        >


    c) The commands are now where you want them to, but they still look gray and dull.  Styling them requires two actions, first I had to add an implicit style for Buttons to the resources of the CommandGroupPresenter.  To avoid duplication, I based this resource on the same resource dictionary that styles 'my Cosmopolitan buttons'.

                    <framework:CommandGroupPresenter.Resources>
                        <ResourceDictionary>
                            <ResourceDictionary.MergedDictionaries>
                                <ResourceDictionary Source="/ClientControls;component/Cosmopolitan/Presentation/Themes/ButtonStyles.xaml" />
                            </ResourceDictionary.MergedDictionaries>
                            <Style TargetType="Button" BasedOn="{StaticResource ImageCollectionButtonStyle}" >
                                <Setter Property="Width" Value="15" />
                            </Style> 
                            
                        </ResourceDictionary>                   
                    </framework:CommandGroupPresenter.Resources> 

    Now the gray buttons will look like nifty Cosmo icons, but they are spaced out miles apart.  I couldn't fix this with a style because something the LS framework seems to override the MinWidth no matter how hard I try... Hence this code:

            private void CommandGroupPresenterElement_Loaded(object sender, RoutedEventArgs e)
            {
                var grid = VisualTreeHelper.GetChild(sender as DependencyObject, 0) as Grid;
                var stackPanel = VisualTreeHelper.GetChild(grid, 0) as StackPanel; 
    
                foreach( var commandPresenter in stackPanel.Children.OfType<Microsoft.LightSwitch.Presentation.Framework.ContentItemPresenter>()){
                    var layoutContentPresenter = VisualTreeHelper.GetChild(commandPresenter, 0) as
                        Microsoft.LightSwitch.Presentation.Framework.LayoutContentPresenter; 
                    layoutContentPresenter.MinWidth = 15; 
                }
    
            }

    And there we go...

    Now, was that really so hard?  ;-p

    Keep rocking LS

    Jan


    It's your story - time to switch on the innovation.||About me||LightSwitch blog

    Friday, October 25, 2013 3:25 PM

All replies

  • And additionally...

    I only just started on these commands so my apologies that I missed this obvious flaw... I just noticed that the commands are already shown by default underneath my collection control.  

    Wow... Any way to disable that? 

    Thanks

    Jan


    It's your story - time to switch on the innovation.||About me||LightSwitch blog

    Monday, October 21, 2013 11:50 AM
  • Hi,

    As you just started on the commands, I’d like to suggest you to refer to the link below:

    Creating A LightSwitch Collection Control Extension

    http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/104/Creating-A-LightSwitch-Collection-Control-Extension.aspx

    I think it will be helpful to you.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, October 22, 2013 12:31 PM
    Moderator
  • Hey Junjie,

    thanks for that link, it did help me getting started with collection controls at first.

    However, Michael, the author, has captured everything he knows about collection controls in that article (as he states so in the comments) and the article clearly shows (first and last picture) the same flaw as I' trying to fix: no matter how fancy your collection control is, LightSwitch slaps on gray buttons with no way for you to style them... :(  

    Any additional hints are still very much welcomed.

    Thanks,

    Jan


    It's your story - time to switch on the innovation.||About me||LightSwitch blog

    Wednesday, October 23, 2013 6:43 AM
  • Found it...

    For those LS hackers among you, here's the 1-2-3 for future reference.

    a) To hide the default gray command buttons that are placed underneath your user control by default, add an event handler to your control's Loaded event, then walk up the visual tree to find the grid that holds both your control and the automagically added gray command buttons, and hide them.

            void MyUserControl_Loaded(object sender, RoutedEventArgs e)
            {
                //find Microsoft.LightSwitch.Presentation.Framework.AutoCommandGroupPresenterGrid
                Grid host = FindUpVisualTree<Grid>(this); 
                //hide default controls
                host.Children[1].Visibility = System.Windows.Visibility.Collapsed; 
            }
    
            // walk up the visual tree to find object of type T, starting from initial object
            // Modified from http://www.codeproject.com/Tips/75816/Walk-up-the-Visual-Tree
            public static T FindUpVisualTree<T>(DependencyObject initial) where T : DependencyObject
            {
                DependencyObject current = initial;
    
                while (current != null && !typeof(T).IsAssignableFrom(current.GetType()))
                {
                    current = VisualTreeHelper.GetParent(current);
                }
                return current as T;
            }


    b) To add the command buttons in a place where you want them, simply add a "CommandGroupPresenter" where you need one.

    Reference:

        xmlns:framework="clr-namespace:Microsoft.LightSwitch.Presentation.Framework;assembly=Microsoft.LightSwitch.Client"

    Code:

                <framework:CommandGroupPresenter 
                                        x:Name="CommandGroupPresenterElement"   
                                        Commands="{Binding ContentItem.CommandItems}" 
                                        HorizontalAlignment="Left" 
                                        VerticalAlignment="Bottom" 
                                        HorizontalContentAlignment="Left"
                                        Margin="3,5,3,8" 
                                        TabIndex="1" 
                                        ContainerState="IntegratedCommandGroup" 
                                        Loaded="CommandGroupPresenterElement_Loaded"
                                        >


    c) The commands are now where you want them to, but they still look gray and dull.  Styling them requires two actions, first I had to add an implicit style for Buttons to the resources of the CommandGroupPresenter.  To avoid duplication, I based this resource on the same resource dictionary that styles 'my Cosmopolitan buttons'.

                    <framework:CommandGroupPresenter.Resources>
                        <ResourceDictionary>
                            <ResourceDictionary.MergedDictionaries>
                                <ResourceDictionary Source="/ClientControls;component/Cosmopolitan/Presentation/Themes/ButtonStyles.xaml" />
                            </ResourceDictionary.MergedDictionaries>
                            <Style TargetType="Button" BasedOn="{StaticResource ImageCollectionButtonStyle}" >
                                <Setter Property="Width" Value="15" />
                            </Style> 
                            
                        </ResourceDictionary>                   
                    </framework:CommandGroupPresenter.Resources> 

    Now the gray buttons will look like nifty Cosmo icons, but they are spaced out miles apart.  I couldn't fix this with a style because something the LS framework seems to override the MinWidth no matter how hard I try... Hence this code:

            private void CommandGroupPresenterElement_Loaded(object sender, RoutedEventArgs e)
            {
                var grid = VisualTreeHelper.GetChild(sender as DependencyObject, 0) as Grid;
                var stackPanel = VisualTreeHelper.GetChild(grid, 0) as StackPanel; 
    
                foreach( var commandPresenter in stackPanel.Children.OfType<Microsoft.LightSwitch.Presentation.Framework.ContentItemPresenter>()){
                    var layoutContentPresenter = VisualTreeHelper.GetChild(commandPresenter, 0) as
                        Microsoft.LightSwitch.Presentation.Framework.LayoutContentPresenter; 
                    layoutContentPresenter.MinWidth = 15; 
                }
    
            }

    And there we go...

    Now, was that really so hard?  ;-p

    Keep rocking LS

    Jan


    It's your story - time to switch on the innovation.||About me||LightSwitch blog

    Friday, October 25, 2013 3:25 PM
  • Although that first bit of code is more bug-free as:

                //find Microsoft.LightSwitch.Presentation.Framework.AutoCommandGroupPresenterGrid
                Grid host = FindUpVisualTree<Grid>(this); 
                //hide default controls
                var children = host.Children.Where(c => c.GetType().Name == "CommandGroupPresenter");
                foreach (var autoCommandGroupPresenterGrid in children)
                {
                    autoCommandGroupPresenterGrid.Visibility = Visibility.Collapsed;
                }


    It's your story - time to switch on the innovation.||About me||LightSwitch blog

    Monday, November 4, 2013 1:17 AM
  • Instead of using code to hide the commands that are automatically shown, specify that the CommandItemsSupport property on your Control definition in the LSML file is set to CustomDisplay. This means that the control will handle showing commands itself rather than letting the LightSwitch runtime show them.

    Justin Anderson, LightSwitch Development Team

    Monday, November 4, 2013 2:28 AM
    Moderator
  • Justin you stud,

    that is just purfect.  One of these days I'm going to steal the LSML dictionary inside your head, hehe!

    Thanks a million

    Keep rocking LS!

    Jan


    It's your story - time to switch on the innovation.||About me||LightSwitch blog

    Monday, November 4, 2013 2:19 PM
  • Hey,

    I'm building a LightSwitch 2013 HTML app.

    By default, the command bar of the screen is located in the footer (the bottom of every screen).

    How can i change that to be in the header of every screen?

    today i'm doing something like this:

    inside the created function of every screen:

    window.onpageshow = function ()
        {
            // Move footer to header
            var footer = document.getElementsByClassName("ui-footer-fixed")[0];
            if (footer != undefined && footer != null)
            {
                footer.className = footer.className.replace("ui-footer-fixed", "ui-header-fixed");
            }
        }

    This works but not so good ---> The user can see that the command-bar is positioned in the bottom of the screen and then it goes to the top of the screen.

    I want to force the command bar to be on the header of all screens without putting that code on every screen.

    Any ideas?

    Thanks.

    Tuesday, February 16, 2016 6:50 AM
  • Hey Yaron!

    It's better to start a new thread for this, as it's a different technology (SL vs HTML) but also because the thread is old and already has an answer, so less people are likely to come visit it.

    As per your problem: there's no need to change the structure of the HTML. Find all CSS that relates to ui-header-fixed, then in user-customizations.css, copy it but for the ui-footer-fixed.  IE: make the CSS do the work, don't try to change the structure of the HTML

    J

    Tuesday, February 16, 2016 7:56 AM