XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using Microsoft.UI.Xaml.Media;
using System.Runtime.CompilerServices;

namespace XFEEDToolBox.Controls;

internal static class OutfittingSelectorSizing
{
    private static readonly ConditionalWeakTable<ItemsView,object> Observed=new();
    public static void Fit(SelectorBar selector)
    {
        selector.ApplyTemplate();
        var items=Find<ItemsView>(selector);
        if(items is null||selector.Items.Count==0)return;
        if(!Observed.TryGetValue(items,out _))
        {
            Observed.Add(items,new());
            items.SizeChanged+=(_,_)=>Fit(selector);
        }
        items.ApplyTemplate();
        if(items.ScrollView is {} scroll)
        {
            scroll.ContentOrientation=ScrollingContentOrientation.Vertical;
            scroll.HorizontalScrollMode=ScrollingScrollMode.Disabled;
            scroll.VerticalScrollMode=ScrollingScrollMode.Disabled;
            scroll.HorizontalScrollBarVisibility=ScrollingScrollBarVisibility.Hidden;
            scroll.VerticalScrollBarVisibility=ScrollingScrollBarVisibility.Hidden;
        }
        var available=(items.ScrollView?.ViewportWidth is >0?items.ScrollView.ViewportWidth:items.ActualWidth)-items.Padding.Left-items.Padding.Right;
        if(available<=0)return;
        var spacing=(items.Layout as StackLayout)?.Spacing??0;
        // Share actual pixels as well as layout units. Independently rounding
        // four fractional widths at 150% scaling can create a scroll extent.
        var scale=selector.XamlRoot?.RasterizationScale??1;
        var pixels=Math.Max(0,(int)Math.Floor(available*scale)-(int)Math.Round(spacing*scale)*(selector.Items.Count-1));
        var width=pixels/selector.Items.Count;var remainder=pixels%selector.Items.Count;
        for(var index=0;index<selector.Items.Count;index++)
        {
            var item=selector.Items[index];
            item.Margin=new(0);
            item.MinWidth=0;
            item.Width=(width+(index<remainder?1:0))/scale;
        }
    }

    private static T? Find<T>(DependencyObject root) where T:DependencyObject
    {
        if(root is T found)return found;
        for(var i=0;i<VisualTreeHelper.GetChildrenCount(root);i++)
            if(Find<T>(VisualTreeHelper.GetChild(root,i)) is {} child)return child;
        return null;
    }
}