dotnet / winforms

Windows Forms is a .NET UI framework for building Windows desktop applications.
MIT License
4.36k stars 966 forks source link

a container like QStackedWidget in Qt and StackPane in JavaFx #3765

Open ismlsmile opened 4 years ago

ismlsmile commented 4 years ago

1.what exactly is that you require (including screenshots, documentation, etc.) https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/StackPane.html https://doc.qt.io/qt-5/qstackedwidget.html

2.what benefits the new control provide and what use cases it will address several widgets put together, and only one widget is shown at any time.

3.what underlying Windows control/functionality it will map to a tab control without tab headers

4.the API surface, maybe "SetCurrentIndex"

5.designer requirements need to be integarated into ide

6.accessibility requirements no

Sorry, English is not my mother language, so I could not express well. And I saw What @weltkante reply is really what I want. So if @weltkante could see this post again, please suppliment some more infomation if you could, thanks very much.

weltkante commented 4 years ago

As mentioned in #3759 there is utility to such a control and I've implemented one in the past, so I'm filling the template based on the experience from my implementation. The question whether to provide something out of the box or leave it to be provided by 3rd party packages is open for the team to decide.

Is your feature request related to a problem? Please describe. Provide a control which allows switching between different pages, like a TabControl but without header UI.

It is common to have different controls visible in the same area for different states of a form, common workarounds are to use multiple controls placed on the same position and switching visibility. This is inconvenient in the designer. More complex setups use multiple panels over the same area and switch visibility of panels, but this still is annoying to design since you have to bring the panel you want to edit to the front, which changes control order (bad for version history). The logical conclusion is to have a control which switches visibility automatically, and have designer integration to let you flip through the panels without changing their order. This is very close in functionality that TabControl already provides for its TabPages.

Other frameworks have a dedicated control for this scenario, according to OP for example QStackedWidget in Qt and StackPane in JavaFx.

PS: the name StackPanel I've chosen in this proposal is up for discussion, since WPF/UWP/WinUI use this name with a different semantic than the quoted third party frameworks, they interpret the "stacking" term as providing automatic layout stacking controls horizontally/vertically, instead of stacking controls "on top" of each other.

Describe the solution you'd like and alternatives you've considered TabControl has the design-time functionality that is desirable, but provides additional tab headers which are not desireable in this scenario, since page flipping will be implemented by code only to show the page which is appropriate for the current state.

The proposal is to use TabControl as a starting point for the API and implementation, but instead of wrapping the native tab control just implement a plain control. Since panel switching is done entirely through code there is no complex UI required.

public class StackPanel : Control, ISupportInitialize
{
    public event EventHandler SelectedIndexChanged;
    public int SelectedIndex { get; set; }
    public StackPage SelectedPage { get; set; }
    public int PageCount { get; }
    public StackPageCollection Pages { get; }

    // StackPageCollection can be implemented equivalently to TabPageCollection, omitted for brevity

    // besides the above public API some designer properties make no sense and should be suppressed
    // - Text makes no sense, should be suppressed
    // - TabStop should default to false
}

[ToolboxItem(false)]
public class StackPage : Panel
{
    // No public API required, but designer support. Also similar to TabPage suppress some designer properties
    // - Layout properties should be suppressed since the container controls them
    //   (Location, Size, Anchor, Dock, AutoSize, AutoSizeMode, PreferredSize, MinimumSize, MaximumSize)
    // - TabIndex makes no sense, only one page is ever visible, should be suppressed
    // - Text makes no sense, should be suppressed
    // - Visible should be suppressed in the designer only since it is controlled by the parent control
}

The commonly used workaround if such a control is not available (besides coding it yourself) is to inline the individual pages into the parent container and change the visibility directly. This is very awkward at design time however.

Screenshot of the desired design-time interaction (as currently implemented in my own solution). As you see its pretty similar to TabControl except there's a dropdown to switch the current page. Like when switching tabs of a TabControl in the designer this dropdown does not change the persisted SelectedIndex, it is only for showing and editing other pages in the designer.

grafik

Will this feature affect UI controls? Yes, this will provide a new kind of container control for the designer. I don't know how the new designer works, in Desktop designer integration was part of the framework so it was extensible. If the new designer requires special handling for TabControls it likely will need special handling for this container as well to provide the necessary design-time user interaction.

Accessibility should treat this like a container. Might need some special coding to reduce the double nesting to a single layer, but perhaps this already works out of the box since the container inherits from Control and the pages inherit from Panel.

Localization of the control itself is not required (of course design time UI may display text that needs to be localized, but its a fixed localization, it does not need to be localizable by the consumer of the control - the end user never sees this localization)

ismlsmile commented 4 years ago

@weltkante thanks again for your great help.