microsoft / microsoft-ui-xaml

Windows UI Library: the latest Windows 10 native controls and Fluent styles for your applications
MIT License
6.34k stars 677 forks source link

Feature Proposal: Layout Anchors #4027

Open dotMorten opened 3 years ago

dotMorten commented 3 years ago

iOS has a great concept of layout anchors. You can for instant link control A's top anchor to the bottom of control B. So if control A moves down, control B's top will move down with it. This is a bit like the relative layout panel, but without the need for a relative layout, and provides a lot of additional flexibility. And it becomes a lot more advanced once you start exposing additional anchors in your control besides the normal top/bottom/left/right/center/width/height anchors.

For example, you can start exposing anchors of internal elements:

public class MyControl : Control
{
    public Anchor TopOfTextAnchor => _internalTextElement.TopAnchor;
}

Now it becomes possible to align other controls with specific parts of a custom control's internal design elements. This is extremely powerful to make great connected layouts, especially during animation etc, or if the internal text element gets larger, or moves.

public class FrameworkElement
{
    public Anchor TopAnchor { get; }
    public Anchor BottomAnchor { get; }
    public Anchor LeftAnchor { get; }
    public Anchor RightAnchor { get; }
    public Anchor HorizontalCenterAnchor { get; }
    public Anchor VerticalCenterAnchor { get; }
    public Anchor WidthAnchor { get; }
    public Anchor HeightAnchor { get; }
}

The anchor class would also provide an offset value. So you could align the top of one control with the bottom of another, and add a bit of extra margin, or ensure they have the same size. Example:

<TextBox x:Name="tb1" />
<TextBox x:Name="tb2" 
       TopAnchor.ConstrainTo="tb1.BottomAnchor, Offset=50" 
       WidthAnchor.ConstrainTo="tb1.WidthAnchor"  />
ranjeshj commented 3 years ago

@chrisglein @MikeHillberg as FYI.

mdtauk commented 3 years ago

How different is this to the RelativePanel, which also does positioning based on other elements in the panel?

https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.relativepanel?view=winrt-19041

dotMorten commented 3 years ago

@mdtauk It would negate the need for relative panel (and be able to be used anywhere), but the main difference is in the first example I provided, where a control could have multiple custom anchors in addition to just the edges. It can also work across multiple panels

anawishnoff commented 3 years ago

I think this is a great idea - this would create a ton of flexibility in layouts and make it easier to create more complex layouts. I also like the idea of internal elements having anchors, which would definitely help with animation, but also would generally provide new functionality in terms of aligning things exactly the way you want them.

Anchors may also provide some cool stuff in the way of navigation - I'm thinking about how in html/js you can use an anchor to scroll or navigate directly to a part of a page. This may be useful in WinUI as well, especially when I think of apps that use infinite scroll and things of that nature.

Conceptually, I'm thinking of this sort of being like making the entire app one big RelativePanel, but with more specific and targeted "relations" for each element. @ranjeshj Any thoughts on the performance impact of something like this?