[CLOSED] SplitButton overflow menu not shown correctly

Page 1 of 2 12 LastLast
  1. #1

    [CLOSED] SplitButton overflow menu not shown correctly

    Hello support team,
    please refer to a considerably simplified test case of relatively sophisticated application toolbar rendering (based on button groups / buttons registration and user preferences). When using SplitButton in the toolbar, I noticed the strange behavior of the overflow menu.

    _LayoutPartial.cshtml:
    @{
        Layout = null;
        var X = Html.X();
    }
    
    @(Html.X().ResourceManager())
    
    @{Container container = X.Container().ItemsFromPartial("ApplicationToolbar");}
    
    @(
        X.Window().Width(400).Height(200).Items(
            X.Panel()
            .Layout(LayoutType.Fit)
            .BodyPadding(0)
            .Border(false)
            .DockedItems(container)
            .ItemsFromSection(this, "ITEMS", true)
        )
    )
    
    @RenderBody()
    ApplicationToolbar.cshtml:
    @using TestCases.Models;
    
    @{AppToolbarRenderer renderer = new AppToolbarRenderer();}
    
    @renderer.RenderApplicationToolbar()
    Index.cshtml:
    @{
        Layout = "~/Views/Shared/_LayoutPartial.cshtml";
        var X = Html.X();
    }
    
    @section ITEMS {}
    ToolbarModel.cs:
    using Ext.Net;
    
    namespace TestCases.Models
    {
        public class AppToolbarRenderer
        {
            public Toolbar.Builder RenderApplicationToolbar()
            {
                Toolbar toolbar = new Toolbar()
                {
                    Border = false,
                    Dock = Dock.Top,
                    EnableOverflow = true,
                    OverflowHandler = OverflowHandler.Menu
                };
    
                toolbar.Plugins.Add(new BoxReorderer());
                toolbar.LayoutConfig.Add(new HBoxLayoutConfig() { Align = HBoxAlign.Stretch });
    
                ButtonGroup grpSave = new ButtonGroup { Title = "Save" };
    
                // just to make toolbar wider:            
                grpSave.Items.Add(new Button { Icon = Icon.Disk, IconAlign = IconAlign.Top, Text = "Save" });
                grpSave.Items.Add(new Button { Icon = Icon.DiskEdit, IconAlign = IconAlign.Top, Text = "Save+New" });
                grpSave.Items.Add(new Button { Icon = Icon.DiskMagnify, IconAlign = IconAlign.Top, Text = "Save+Clone" });
                grpSave.Items.Add(new Button { Icon = Icon.DiskError, IconAlign = IconAlign.Top, Text = "Save+Close" });
    
                ButtonGroup grpOutput = new ButtonGroup { Title = "Output", Columns = 2 };
    
                SplitButton btn1 = AppToolbarSplitButton.Print();
                btn1.Menu[0].Add(new Ext.Net.MenuItem("Print Option 1"));
                btn1.Menu[0].Add(new Ext.Net.MenuItem("Print Option 2"));
    
                SplitButton btn2 = AppToolbarSplitButton.Preview();
                btn2.Menu[0].Add(new Ext.Net.MenuItem("Preview Option 1"));
                btn2.Menu[0].Add(new Ext.Net.MenuItem("Preview Option 2"));
    
                SplitButton btn3 = AppToolbarSplitButton.Pdf();
                btn3.Menu[0].Add(new Ext.Net.MenuItem("Pdf Option 1"));
                btn3.Menu[0].Add(new Ext.Net.MenuItem("Pdf Option 2"));
    
                grpOutput.Items.Add(btn1);
                grpOutput.Items.Add(btn2);
                grpOutput.Items.Add(btn3);
    
                toolbar.Items.Add(grpSave);
                toolbar.Items.Add(grpOutput);
    
                return toolbar.ToBuilder();
            }
        }
    
        public class AppToolbar : Toolbar { }
    
        public class AppToolbarSplitButton : SplitButton
        {
            public AppToolbarSplitButton()
            {
                Scale = ButtonScale.Small;
                IconAlign = IconAlign.Top;
            }
    
            public static AppToolbarSplitButton Print()
            {
                AppToolbarSplitButton btn = new AppToolbarSplitButton
                {
                    Icon = Icon.Printer,
                    Text = "Print",
                    OverflowText = "Print",
                    ArrowVisible = false,
                    RowSpan = 2
                };
    
                Menu m = new Menu();
                m.Listeners.Add.Handler = "if (this.items.length == 1) { this.ownerCmp.setArrowVisible(true); if (this.ownerCmp.ownerCt && !this.ownerCmp.ownerCt.hidden) this.ownerCmp.ownerCt.updateLayout(); }"; // show arrow after the first menu item is added
    
                btn.Menu.Add(m);
    
                return btn;
            }
    
            public static AppToolbarSplitButton Preview()
            {
                AppToolbarSplitButton btn = new AppToolbarSplitButton
                {
                    Icon = Icon.Layout,
                    IconAlign = IconAlign.Left,
                    Text = "Preview",
                    TextAlign = ButtonTextAlign.Left,
                    OverflowText = "Preview",
                    ArrowVisible = false,
                    WidthSpec = "100%"
                };
    
                Menu m = new Menu();
                m.Listeners.Add.Handler = "if (this.items.length == 1) { this.ownerCmp.setArrowVisible(true); if (this.ownerCmp.ownerCt && !this.ownerCmp.ownerCt.hidden) this.ownerCmp.ownerCt.updateLayout() }";
                btn.Menu.Add(m);
    
                return btn;
            }
    
            public static AppToolbarSplitButton Pdf()
            {
                AppToolbarSplitButton btn = new AppToolbarSplitButton
                {
                    Icon = Icon.PageWhiteAcrobat,
                    IconAlign = IconAlign.Left,
                    Text = "PDF",
                    TextAlign = ButtonTextAlign.Left,
                    OverflowText = "PDF",
                    ArrowVisible = false,
                    WidthSpec = "100%"
                };
    
                Menu m = new Menu();
                m.Listeners.Add.Handler = "if (this.items.length == 1) { this.ownerCmp.setArrowVisible(true); if (this.ownerCmp.ownerCt && !this.ownerCmp.ownerCt.hidden) this.ownerCmp.ownerCt.updateLayout() }";
    
                btn.Menu.Add(m);
    
                return btn;
            }
        }
    }
    There are several issues accountered here:
    1. The overflow menu is displayed incorrectly (it takes the full width of the browser)
    2. After toolbar (window) resize, the menu on split buttons is not shown
    3. After toolbar (window) resize, the "Output" button group and the "Overflow" menu button are rendered "randomly" - shown/hidden independently on the available space

    Am I doing something wrong?

    Ext.NET 4.7.1
    Ext JS 6.6.0.258

    Thank you for your assistance.

    Dan
    Last edited by fabricio.murta; Oct 10, 2018 at 3:51 PM.
  2. #2
    Hello, @NewLink!

    Thanks for trying to simplify the test case, we have tried to run it but it seems, after adding all code, at least the controllers code is missing. Have you tried to reduce this issue down to single-page, all rendered from razor code? It would be interesting to know if the page issues are introduced because of partial views, or due to the way you build the components (via model calls).

    Maybe this can still be simplified down to a one-page, one-file WebForms page, with just the bare minimum to reproduce the issue? Or if you try it, you get the correct output?

    Here something I've tried, but can't say I'm really reproducing the page you want to draw:

    <%@ Page Language="C#" %>
    
    <!DOCTYPE html>
    
    <script runat="server">
        public void Page_Load(object sender, EventArgs e)
        {
            // just in case some code behind algorithm is necessary.
        }
    
    </script>
    <html>
    <head runat="server">
        <title>Ext.NET Example</title>
    
    </head>
    <body>
        <form id="Form1" runat="server">
            <ext:ResourceManager runat="server" />
            <ext:Window runat="server" ID="wnd1" Width="400" Height="200">
                <Items>
                    <ext:Panel runat="server" ID="pnl1" BodyPadding="0" Border="false">
                        <DockedItems>
                            <ext:Toolbar runat="server" ID="tlb1" Dock="Top" EnableOverflow="true" OverflowHandler="Menu">
                                <LayoutConfig><ext:HBoxLayoutConfig Align="Stretch" /></LayoutConfig>
                                <Plugins>
                                    <ext:BoxReorderer runat="server" ID="brp1" />
                                </Plugins>
                                <Items>
                                    <ext:Button runat="server" ID="btn1" Icon="Disk" Text="Save" IconAlign="Top" />
                                    <ext:Button runat="server" ID="btn2" Icon="DiskEdit" Text="Save+New" IconAlign="Top" />
                                    <ext:Button runat="server" ID="btn3" Icon="DiskMagnify" Text="Save+Clone" IconAlign="Top" />
                                    <ext:Button runat="server" ID="btn4" Icon="DiskError" Text="Save+Close" IconAlign="Top" />
                                    <ext:ButtonGroup runat="server" ID="btg1" Title="Output" Columns="2">
                                        <Items>
                                            <ext:SplitButton runat="server" ID="sbt1" Icon="Printer" Text="Print" RowSpan="2">
                                                <Menu>
                                                    <ext:Menu runat="server" ID="mnu1">
                                                        <Items>
                                                            <ext:MenuItem runat="server" Text="Print Option 1" />
                                                            <ext:MenuItem runat="server" Text="Print Option 2" />
                                                        </Items>
                                                    </ext:Menu>
                                                </Menu>
                                            </ext:SplitButton>
                                            <ext:SplitButton runat="server" ID="sbt2" Icon="Layout" Text="Preview" RowSpan="2">
                                                <Menu>
                                                    <ext:Menu runat="server" ID="mnu2">
                                                        <Items>
                                                            <ext:MenuItem runat="server" Text="Preview Option 1" />
                                                            <ext:MenuItem runat="server" Text="Preview Option 2" />
                                                        </Items>
                                                    </ext:Menu>
                                                </Menu>
                                            </ext:SplitButton>
                                            <ext:SplitButton runat="server" ID="sbt3" Icon="Printer" Text="PDF" RowSpan="2">
                                                <Menu>
                                                    <ext:Menu runat="server" ID="mnu3">
                                                        <Items>
                                                            <ext:MenuItem runat="server" Text="PDF Option 1" />
                                                            <ext:MenuItem runat="server" Text="PDF Option 2" />
                                                        </Items>
                                                    </ext:Menu>
                                                </Menu>
                                            </ext:SplitButton>
                                        </Items>
                                    </ext:ButtonGroup>
                                </Items>
                            </ext:Toolbar>
                        </DockedItems>
                    </ext:Panel>
                </Items>
            </ext:Window>
        </form>
    </body>
    </html>
    Fabrício Murta
    Developer & Support Expert
  3. #3
    Hi FabrÃ*cio,
    thank you for answer. I understand your reproach very well and you are right... it was not simplified enough.

    I did not mention the controller because it is very simple:
    using System.Web.Mvc;
    
    namespace TestCases.Controllers
    {
        public class ToolbarController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
        }
    }
    In my view, the way the toolbar is built has a significant effect on the result. I will try to simplify the test case even more so that I get the complained output with a minimum code. I will reply later.

    Thank you for assistance.

    Dan
    Last edited by NewLink; Sep 12, 2018 at 11:11 PM.
  4. #4
    Hi FabrÃ*cio,
    a simplified test case is here:
    @{
        Layout = null;
        var X = Html.X();
    
        AbstractComponent[] toolbar = new AbstractComponent[]
        {
            X.Toolbar().Border(false).Dock(Dock.Top).EnableOverflow(true).OverflowHandler(OverflowHandler.Menu).LayoutConfig(new HBoxLayoutConfig() { Align = HBoxAlign.Stretch }).Items(
                X.ButtonGroup().Title("Output").Columns(2).Items(
                    X.SplitButton().Text("Print").OverflowText("Print").Icon(Icon.Printer).RowSpan(2).Scale(ButtonScale.Large).Menu(
                        X.Menu().Items(
                            X.MenuItem().Text("Print Option 1"),
                            X.MenuItem().Text("Print Option 2")
                        )
                    ),
                    X.SplitButton().Text("Preview").OverflowText("Preview").Icon(Icon.Layout).IconAlign(IconAlign.Left).TextAlign(ButtonTextAlign.Left).WidthSpec("100%").Menu(
                        X.Menu().Items(
                            X.MenuItem().Text("Preview Option 1"),
                            X.MenuItem().Text("Preview Option 2")
                        )
                    ),
                    X.SplitButton().Text("PDF").OverflowText("PDF").Icon(Icon.PageWhiteAcrobat).IconAlign(IconAlign.Left).TextAlign(ButtonTextAlign.Left).WidthSpec("100%").Menu(
                        X.Menu().Items(
                            X.MenuItem().Text("Pdf Option 1"),
                            X.MenuItem().Text("Pdf Option 2")
                        )
                    )
                )
            )
        };
    }
    
    @(Html.X().ResourceManager())
    
    @(
        X.Window().Width(100).Height(150).Items(
            X.Panel()
            .Layout(LayoutType.Fit)
            .BodyPadding(0)
            .Border(false)
            .DockedItems(toolbar)
        )
    )
    I apologize for my laziness to provide a meaningful test case right from the start.

    Dan
  5. #5
    Hello @NewLink!

    Alright, now it is very clear what's up! Thank you for taking your time to simplify the issue!

    The issue is with the WidthSpec="100%" in your code. It is making the menu entry occupy all the width when displayed in the overflow menu.

    I believe you want something similar to MS-Office look & feel, right? Aligned buttons, and the group collapses in its entirety when it does not fit the window width, leaving other button groups if they still fit there (left-aligned).

    If my guess is correct, the default column layout assigned to button groups is not ideal, and you can just wrap button groups as containers in horizontal-vertical wrapping to have the same column behavior, yet ensuring better dynamic readjustment as the window is resized.

    Here's a suggestion to fix your scenario.

    In summary:

    - uses vbox/hbox layout on button groups instead of the column layout
    - drops .WidthSpec("100%") from buttons in favor of the .Flex(1)
    - arranges vertically-aligned buttons within inner vbox-aligned button groups (vertical button groups within horizontal button groups) to mimic the column behavior and dynamically fit components to the available width
    - guarantees minimum button group width (could use also MaxWidth to determine its maximum, or just give fixed widths so that buttons therein are always the same width)
    - addresses an issue where buttons are hidden to the overflow menu, expanded, re-displayed in the toolbar, and expanded (menu was not then showing up anymore)

    I hope this is a suitable approach for your scenario.

    @{
        Layout = null;
        var X = Html.X();
    }
    
    @(Html.X().ResourceManager())
    
    @(
        // Resizable window
        X.Window().Width(100).Height(180).DockedItems(
            // Toolbar, stretching its entries horizontally to fit its width.
            X.Toolbar()
                .Border(false)
                .Dock(Dock.Top)
                .EnableOverflow(true) // This already implies .OverflowHandler(OverflowHandler.Menu)
                .LayoutConfig(new HBoxLayoutConfig() { Align = HBoxAlign.Stretch })
                .Items(
                    // Outer button group, ensuring everything on it will be hidden whenever any part
                    // of it does not fit the toolbar's width.
                    X.ButtonGroup()
                        .Title("Output")
                        .Flex(1)
                        .MinWidth(300)
                        .LayoutConfig(new HBoxLayoutConfig() { Align = HBoxAlign.Stretch })
                        .Items(
                            X.SplitButton()
                                .Text("Print")
                                .OverflowText("Print")
                                .Icon(Icon.Printer)
                                .Scale(ButtonScale.Large)
                                .Flex(1)
                                .Menu(
                                    X.Menu().Items(
                                        X.MenuItem().Text("Print Option 1"),
                                        X.MenuItem().Text("Print Option 2")
                                    )
                                )
                                // This listener fixes an issue that prevents the menu from showing
                                // when the button is once expanded via the overflow menu and then
                                // displayed again. Should be present in all instances of the split
                                // buttons.
                                .Listeners(l => l.MenuShow.Handler = Ext.Net.MvcUtils.StringifyScriptBlock(@<text>
                                    <script>
                                        if (this.menu.ownerCmp !== this) {
                                            this.menu.setOwnerCmp(this);
                                        }
                                    </script>
                                </text>)),
                                // A vertical-filling button group for the buttons spanning one row each.
                                X.ButtonGroup()
                                    .Flex(1)
                                    .LayoutConfig(new VBoxLayoutConfig() { Align = VBoxAlign.Stretch })
                                    .Items(
                                        X.SplitButton()
                                            .Text("Preview")
                                            .OverflowText("Preview")
                                            .Icon(Icon.Layout)
                                            .IconAlign(IconAlign.Left)
                                            .TextAlign(ButtonTextAlign.Left)
                                            .Flex(1)
                                            .Menu(
                                                X.Menu().Items(
                                                    X.MenuItem().Text("Preview Option 1"),
                                                    X.MenuItem().Text("Preview Option 2")
                                                )
                                            )
                                            .Listeners(l => l.MenuShow.Handler = Ext.Net.MvcUtils.StringifyScriptBlock(@<text>
                                                <script>
                                                    if (this.menu.ownerCmp !== this) {
                                                        this.menu.setOwnerCmp(this);
                                                    }
                                                </script>
                                            </text>)),
                                        X.SplitButton()
                                            .Text("PDF")
                                            .OverflowText("PDF")
                                            .Icon(Icon.Layout)
                                            .IconAlign(IconAlign.Left)
                                            .TextAlign(ButtonTextAlign.Left)
                                            .Flex(1)
                                            .Menu(
                                                X.Menu().Items(
                                                    X.MenuItem().Text("Pdf Option 1"),
                                                    X.MenuItem().Text("Pdf Option 2")
                                                )
                                            )
                                            .Listeners(l => l.MenuShow.Handler = Ext.Net.MvcUtils.StringifyScriptBlock(@<text>
                                                <script>
                                                    if (this.menu.ownerCmp !== this) {
                                                        this.menu.setOwnerCmp(this);
                                                    }
                                                </script>
                                            </text>))
                                    )
                        )
                )
        )
    )
    And hope this helps!
    Fabrício Murta
    Developer & Support Expert
  6. #6
    Hi FabrÃ*cio,
    thank you for your suggestion. You're right, my intention is to create a toolbar similar to MS Office. Your scenario works well and is almost perfect, but dynamic toolbar readjustment to fill the entire width of the window is not - in my opinion - the best solution. If the toolbar has many button groups, including ToolbarSpacer and ToolbarFill place-holders, the result looks weird.

    However, the introduction of the MenuShow listener has a great value for me because it solves one of the issues I had with the split buttons.

    I slightly modified your code and what I want to achieve is something like this:
    @{
        Layout = null;
        var X = Html.X();
    }
    
    @(Html.X().ResourceManager())
    
    @(
        // Resizable window
        X.Window().Width(400).Height(180).DockedItems(
            // Toolbar, stretching its entries horizontally to fit its width.
            X.Toolbar()
                .Border(false)
                .Dock(Dock.Top)
                .EnableOverflow(true) // This already implies .OverflowHandler(OverflowHandler.Menu)
                .LayoutConfig(new HBoxLayoutConfig() { Align = HBoxAlign.Stretch })
                .Items(
                    // Outer button group, ensuring everything on it will be hidden whenever any part
                    // of it does not fit the toolbar's width.
                    X.ButtonGroup()
                        .Title("Output")
                        //.Flex(1)
                        //.MinWidth(300)
                        .LayoutConfig(new HBoxLayoutConfig() { Align = HBoxAlign.Stretch })
                        .Items(
                            X.SplitButton()
                            .Text("Print")
                            .OverflowText("Print")
                            .IconUrl("http://individual.icons-land.com/IconsPreview/BaseSoftware/PNG/32x32/Printer.png")
                            .Scale(ButtonScale.Large)
                            .Flex(1)
                            .Menu(
                                X.Menu().Items(
                                    X.MenuItem().Text("Print Option 1"),
                                    X.MenuItem().Text("Print Option 2")
                                )
                            )
                            // This listener fixes an issue that prevents the menu from showing
                            // when the button is once expanded via the overflow menu and then
                            // displayed again. Should be present in all instances of the split
                            // buttons.
                            .Listeners(l => l.MenuShow.Handler = Ext.Net.MvcUtils.StringifyScriptBlock(
                                @<text>
                                    <script>
                                        if (this.menu.ownerCmp !== this) {
                                            this.menu.setOwnerCmp(this);
                                        }
                                    </script>
                                </text>)
                            ),
                            X.ButtonGroup()
                                .Flex(1)
                                .LayoutConfig(new VBoxLayoutConfig() { Align = VBoxAlign.Stretch })
                                .Items(
                                    X.SplitButton()
                                        .Text("Preview")
                                        .OverflowText("Preview")
                                        .Icon(Icon.Layout)
                                        .IconAlign(IconAlign.Left)
                                        .TextAlign(ButtonTextAlign.Left)
                                        .Flex(1)
                                        .Menu(
                                            X.Menu().Items(
                                                X.MenuItem().Text("Preview Option 1"),
                                                X.MenuItem().Text("Preview Option 2")
                                            )
                                        )
                                        .Listeners(l => l.MenuShow.Handler = Ext.Net.MvcUtils.StringifyScriptBlock(
                                            @<text>
                                                <script>
                                                    if (this.menu.ownerCmp !== this) {
                                                    this.menu.setOwnerCmp(this);
                                                    }
                                                </script>
                                            </text>)
                                        ),
                                    X.SplitButton()
                                        .Text("PDF")
                                        .OverflowText("PDF")
                                        .Icon(Icon.PageWhiteAcrobat)
                                        .IconAlign(IconAlign.Left)
                                        .TextAlign(ButtonTextAlign.Left)
                                        .Flex(1)
                                        .Menu(
                                            X.Menu().Items(
                                                X.MenuItem().Text("Pdf Option 1"),
                                                X.MenuItem().Text("Pdf Option 2")
                                            )
                                        )
                                        .Listeners(l => l.MenuShow.Handler = Ext.Net.MvcUtils.StringifyScriptBlock(
                                            @<text>
                                                <script>
                                                    if (this.menu.ownerCmp !== this) {
                                                        this.menu.setOwnerCmp(this);
                                                    }
                                                </script>
                                            </text>)
                                        )
                                )
                        ),
                    X.ButtonGroup()
                        .Title("Ext.NET")
                        //.Flex(1)
                        //.MinWidth(300)
                        .LayoutConfig(new HBoxLayoutConfig() { Align = HBoxAlign.Stretch })
                        .Items(
                            X.Button()
                            .Text("Home")
                            .OverflowText("Home")
                            .IconUrl("http://speed.ext.net/identity/extnet-icon-32x32.png")
                            .Scale(ButtonScale.Large)
                            .Flex(1),
                            X.ButtonGroup()
                                .Flex(1)
                                .LayoutConfig(new VBoxLayoutConfig() { Align = VBoxAlign.Stretch })
                                .Items(
                                    X.Button()
                                        .Text("Documentation")
                                        .OverflowText("Documentation")
                                        .Icon(Icon.Page)
                                        .IconAlign(IconAlign.Left)
                                        .TextAlign(ButtonTextAlign.Left)
                                        .Flex(1),
                                    X.Button()
                                        .Text("Examples")
                                        .OverflowText("Examples")
                                        .Icon(Icon.Cog)
                                        .IconAlign(IconAlign.Left)
                                        .TextAlign(ButtonTextAlign.Left)
                                        .Flex(1)
                                )
                        )
                )
        )
    )
    All groups and buttons are now perfectly aligned, but I have two more problems:
    1. When downsized the window an error occures Cannot read property 'setProp' of null.
    2. I'm not able to get rid of outline of the inner button groups.

    It is worth to mention that our framework is multilingual, so working with fixed button/button group width is not possible (because we cannot predict translation string length).

    Is this approach completely wrong or is there any better solution to this scenario?

    Thank you for help.

    Dan
  7. #7
    Hello @NewLink!

    I believe you should tread a little slower on the changes, because your current version of the code throws the exception with setProp during load time and not just when the window is "downsized" (assuming this means minimized? or is that just reduced in width/height?).

    Did you not get this issue on load while making the changes? It would ease pinpointing the reason if you split the changes in "sets" and tested as you go.

    Maybe, a good idea to "replay" the changes and keep an eye open which one triggers the issue? By a quick look at the code I see you removed the 'flex' value but didn't really bind a width value to the button group, so that's a very likely reason it breaks during layout update (which is the context we can see by looking at the call stack when the javascript error is thrown.

    I understand you don't want it just 'flex' around the whole bar, yet you want it to just fit the text within. I'll have to put a little more thought on that before I suggest you a reliable approach, so please wait a little and we'll get back to you with some code.
    Fabrício Murta
    Developer & Support Expert
  8. #8
    Hi FabrÃ*cio,
    I understand your objection, but I did not change the test case too much. I made the window wider (to avoid on load error), turned off Flex and MinWidth on the outer button group and added the same button group once again, but this time with the regular buttons instead of the split buttons (just to be sure both buttons behave the same way). You can easily continue with the initial test case, where you just remove Flex and MinWidth values ​​for Output button group.

    The problem is again with an overflow menu. If the window width was maintained at the initial width of 100, I immediately got an error Cannot read property 'measuresBox' of null during layoutDone. When I set the window width to a value that allows viewing the entire toolbar, no error occurs. Once the window is lowered to launch the overflow menu, it fails again.

    My guess is that the missing width setting causes overflow menu problems, but assigning any width value is not an option for me because I cannot predict the width of all translated strings in a multilingual environment (which our framework is).

    I also tried to get rid of the outline of the inner button groups, but even when I banned all the css classes on the button group, the outline was still there.

    A brief summary of what I want to achieve:
    1. Toolbar with a number of buttons groups separated by ToolbarSpacer and ToolbarFill (no flex or fixed width)
    2. Each button group contains one or more buttons, some of which may be large and some small vertically arranged
    3. All buttons have the width corresponding to the icon/text they contain
    4. All buttons should be nicely aligned - large buttons middle-center, small buttons vertically arranged across the entire toolbar height with aligned width, icons, and texts

    Your scenario - after removing Flex and MinWidth values - is perfect if we get rid of the inner button group outline and overflow menu issues.

    You do not have to hurry, I'll be out of the office for three weeks now, so please take your time.

    Thank you very much for your help.

    Dan
  9. #9
    Hello again, Dan!

    I could notice that the issue was being triggered because the toolbar was not being properly filled up that way. If I just added a ToolbarFill component to the end of the list of ButtonGroups in the toolbar, the issue is no more.

    This happens because without flex, the button groups wouldn't occupy the full toolbar width, thus the gap occurred. The toolbar requires this "filler" component in this situation. If it didn't require it, we could just call that a "panel" or "container", because it adds the "toolbar logic" to a container.

    The min/max width (MinWidth and MaxWidth) does not really make any sense if you are not using any kind of dynamic width adaptation, because the width will be fixed all the time so it will never change to something beyond its boundaries.

    In the end, I have this code:

    @{
        Layout = null;
        var X = Html.X();
    }
    
    @(Html.X().ResourceManager())
    
    @(
        // Resizable window
        X.Window().Width(800).Height(180).DockedItems(
            // Toolbar will consist of several button groups and a toolbar fill in the end for any remaining toolbar space, when it is the case.
            X.Toolbar()
                .Border(false)
                .Dock(Dock.Top)
                .EnableOverflow(true)
                // Just a simple HBox layout should do
                .Layout(LayoutType.HBox)
                .Items(
                    // First button group
                    X.ButtonGroup()
                        .Title("Output")
                        .LayoutConfig(new HBoxLayoutConfig() { Align = HBoxAlign.Stretch })
                        .Items(
                            X.SplitButton()
                            .Text("Print")
                            .OverflowText("Print")
                            .IconUrl("http://individual.icons-land.com/IconsPreview/BaseSoftware/PNG/32x32/Printer.png")
                            .Scale(ButtonScale.Large)
                            .Flex(1)
                            .Menu(
                                X.Menu().Items(
                                    X.MenuItem().Text("Print Option 1"),
                                    X.MenuItem().Text("Print Option 2")
                                )
                            )
                            .Listeners(l => l.MenuShow.Handler = Ext.Net.MvcUtils.StringifyScriptBlock(
                                @<text>
                                    <script>
                                        if (this.menu.ownerCmp !== this) {
                                            this.menu.setOwnerCmp(this);
                                        }
                                    </script>
                                </text>)
                            ),
                            X.ButtonGroup()
                                .Flex(1)
                                .LayoutConfig(new VBoxLayoutConfig() { Align = VBoxAlign.Stretch })
                                .Items(
                                    X.SplitButton()
                                        .Text("Preview")
                                        .OverflowText("Preview")
                                        .Icon(Icon.Layout)
                                        .IconAlign(IconAlign.Left)
                                        .TextAlign(ButtonTextAlign.Left)
                                        .Flex(1)
                                        .Menu(
                                            X.Menu().Items(
                                                X.MenuItem().Text("Preview Option 1"),
                                                X.MenuItem().Text("Preview Option 2")
                                            )
                                        )
                                        .Listeners(l => l.MenuShow.Handler = Ext.Net.MvcUtils.StringifyScriptBlock(
                                            @<text>
                                                <script>
                                                    if (this.menu.ownerCmp !== this) {
                                                        this.menu.setOwnerCmp(this);
                                                    }
                                                </script>
                                            </text>)
                                        ),
                                    X.SplitButton()
                                        .Text("PDF")
                                        .OverflowText("PDF")
                                        .Icon(Icon.PageWhiteAcrobat)
                                        .IconAlign(IconAlign.Left)
                                        .TextAlign(ButtonTextAlign.Left)
                                        .Flex(1)
                                        .Menu(
                                            X.Menu().Items(
                                                X.MenuItem().Text("Pdf Option 1"),
                                                X.MenuItem().Text("Pdf Option 2")
                                            )
                                        )
                                        .Listeners(l => l.MenuShow.Handler = Ext.Net.MvcUtils.StringifyScriptBlock(
                                            @<text>
                                                <script>
                                                    if (this.menu.ownerCmp !== this) {
                                                        this.menu.setOwnerCmp(this);
                                                    }
                                                </script>
                                            </text>)
                                        )
                                )
                        ),
                    // Second button group
                    X.ButtonGroup()
                        .Title("Ext.NET")
                        .LayoutConfig(new HBoxLayoutConfig() { Align = HBoxAlign.Stretch })
                        .Items(
                            X.Button()
                            .Text("Home")
                            .OverflowText("Home")
                            .IconUrl("http://speed.ext.net/identity/extnet-icon-32x32.png")
                            .Scale(ButtonScale.Large)
                            .Flex(1),
                            X.ButtonGroup()
                                .Flex(1)
                                .LayoutConfig(new VBoxLayoutConfig() { Align = VBoxAlign.Stretch })
                                .Items(
                                    X.Button()
                                        .Text("Documentation")
                                        .OverflowText("Documentation")
                                        .Icon(Icon.Page)
                                        .IconAlign(IconAlign.Left)
                                        .TextAlign(ButtonTextAlign.Left),
                                        .Flex(1),
                                    X.Button()
                                        .Text("Examples")
                                        .OverflowText("Examples")
                                        .Icon(Icon.Cog)
                                        .IconAlign(IconAlign.Left)
                                        .TextAlign(ButtonTextAlign.Left)
                                        .Flex(1)
                                )
                        ),
                    // The toolbar fill, necessary to pad the remaining space in the toolbar /when/ there is any.
                    X.ToolbarFill()
                )
        )
    )
    Let us know if you still have trouble setting up the rest of your requirements (centering the buttons, lining them up). This should all be a matter of trying to set up the layouts the way you need.

    If you didn't already, spend some time reviewing the documentation on the different layout types and set ups and you will probably have a much better experience trying to set up layouts the way you need them.

    Hope this helps, and that you have a refreshing out-of-office time.
    Fabrício Murta
    Developer & Support Expert
  10. #10
    Hello Dan!

    It's been some days since we last posted here, and we didn't hear back from you since then. Do you still need help on this issue?

    We may mark this thread as closed in 7+ days from now provided you don't post a followup; but you'll still be able to make posts here regardless of that, so take your time.
    Fabrício Murta
    Developer & Support Expert
Page 1 of 2 12 LastLast

Similar Threads

  1. [CLOSED] change Toolbar overflow menu icons
    By RCM in forum 2.x Legacy Premium Help
    Replies: 4
    Last Post: Jan 16, 2015, 2:28 PM
  2. [CLOSED] Update SplitButton menu on DirectEvent?
    By rthiney in forum 2.x Legacy Premium Help
    Replies: 1
    Last Post: Jun 07, 2013, 4:10 AM
  3. [CLOSED] Updating the Overflow Menu
    By musher in forum 1.x Legacy Premium Help
    Replies: 5
    Last Post: Apr 25, 2012, 2:40 PM
  4. [CLOSED] Splitbutton with Menu - Make the menu expand upwards?
    By rbarr in forum 1.x Legacy Premium Help
    Replies: 2
    Last Post: Aug 02, 2011, 1:18 PM
  5. [CLOSED] Images in SplitButton Menu off
    By rthiney in forum 1.x Legacy Premium Help
    Replies: 1
    Last Post: Mar 01, 2010, 5:50 PM

Posting Permissions