سؤال

When using a Gtk ScrolledWindow with the horizontal Policy Never, I expect the scrolledwindow to adapt, if the horizontal size request of the child changes.

But that's not the case, for example when using an Expander: When I expand the expander, and the child is wider that the scrolled window, the scrolled window doesn't adapt it's size.

Minimum Example:

using System;
using Gtk;

namespace ExpanderIssue
{
    class MainClass
    {
        static bool useExpander = true;

        private static Widget createScrolledWindow(Widget child)
        {
            ScrolledWindow scrolledWindow = new ScrolledWindow();
            scrolledWindow.SetPolicy(PolicyType.Never, PolicyType.Automatic);

            scrolledWindow.AddWithViewport(child);

            return scrolledWindow;
        }

        private static Widget createSingleExpaner(int index)
        {
            Button button = new Button(String.Format("ExampleButton {0}", index));
            button.WidthRequest = 800;

            if(useExpander) {
                Expander expander = new Expander(String.Format("Expander {0}", index));

                expander.Add(button);

                return expander;
            } else {
                return button;
            }
        }

        public static void Main(string[] args)
        {
            Application.Init();

            createMainWindow();

            Application.Run();
        }

        private static Window createMainWindow()
        {
            VBox vbox = new VBox();
            vbox.Spacing = 4;
            for(int i=0; i<32; ++i)
                vbox.PackStart(createSingleExpaner(i), false, false, 0);

            Window mainWindow = new Window("Expander Width Request issue");
            mainWindow.SetDefaultSize(240, 160);
            mainWindow.Add(createScrolledWindow(vbox));
            mainWindow.ShowAll();
            mainWindow.Destroyed += (sender, e) => Application.Quit();

            return mainWindow;
        }
    }
}
هل كانت مفيدة؟

المحلول

Try to create the viewport for your scrollbar manually and adjust the Width Request from viewport when the SizeRequested Event from child is sent.

For your minimal example it should look like this:

using System;
using Gtk;

namespace ExpanderIssue
{
    class MainClass
    {
        static bool useExpander = true;

        private static Widget createScrolledWindow(Widget child)
        {
            ScrolledWindow scrolledWindow = new ScrolledWindow();
            scrolledWindow.SetPolicy(PolicyType.Never, PolicyType.Automatic);

            scrolledWindow.Add(doWorkaround(child));

            return scrolledWindow;
        }

        private static Viewport doWorkaround(Widget child)
        {
            Viewport viewport = new Viewport();

            viewport.Add(child);

            child.SizeRequested += (o, args) =>
            {
                viewport.WidthRequest = viewport.Child.Requisition.Width;
            };

            return viewport;
        }


        private static Widget createSingleExpaner(int index)
        {
            Button button = new Button(String.Format("ExampleButton {0}", index));
            button.WidthRequest = 800;

            if(useExpander) {
                Expander expander = new Expander(String.Format("Expander {0}", index));

                expander.Add(button);

                return expander;
            } else {
                return button;
            }
        }

        public static void Main(string[] args)
        {
            Application.Init();

            createMainWindow();

            Application.Run();
        }

        private static Window createMainWindow()
        {
            VBox vbox = new VBox();
            vbox.Spacing = 4;
            for(int i=0; i<32; ++i)
                vbox.PackStart(createSingleExpaner(i), false, false, 0);

            Window mainWindow = new Window("Expander Width Request issue");
            mainWindow.SetDefaultSize(240, 160);
            mainWindow.Add(createScrolledWindow(vbox));
            mainWindow.ShowAll();
            mainWindow.Destroyed += (sender, e) => Application.Quit();

            return mainWindow;
        }
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top