feat: Add responsive grid Row/Col controls and demo.
This commit is contained in:
1 parent
3aea65a6b9
commit
700abba273
7 files changed
+589
No files matched your search
@@ -0,0 +1,156 @@
|
||||
<UserControl x:Class="HandyControlDemo.UserControl.GridDemo"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||
xmlns:langs="clr-namespace:HandyControlDemo.Properties.Langs"
|
||||
Background="{DynamicResource RegionBrush}">
|
||||
<ScrollViewer>
|
||||
<StackPanel Margin="32">
|
||||
<TextBlock Text="{x:Static langs:Lang.BasicLayout}" Theme="{StaticResource TextBlockLargeBold}" HorizontalAlignment="Left" />
|
||||
<hc:Row Margin="0,20,0,0">
|
||||
<hc:Col Span="24">
|
||||
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
<hc:Row Margin="0,20,0,0">
|
||||
<hc:Col Span="12">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="12">
|
||||
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
<hc:Row Margin="0,20,0,0">
|
||||
<hc:Col Span="8">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
<hc:Row Margin="0,20,0,0">
|
||||
<hc:Col Span="6">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="6">
|
||||
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="6">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="6">
|
||||
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
<hc:Row Margin="0,20,0,0">
|
||||
<hc:Col Span="4">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="4">
|
||||
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="4">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="4">
|
||||
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="4">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="4">
|
||||
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
<TextBlock Text="{x:Static langs:Lang.ColumnSpacing}" Margin="0,32,0,0" Theme="{StaticResource TextBlockLargeBold}" HorizontalAlignment="Left" />
|
||||
<hc:Row Margin="0,20,0,0" Gutter="20">
|
||||
<hc:Col Span="6">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="6">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="6">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="6">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
<TextBlock Text="{x:Static langs:Lang.HybridLayout}" Margin="0,32,0,0" Theme="{StaticResource TextBlockLargeBold}" HorizontalAlignment="Left" />
|
||||
<hc:Row Margin="0,20,0,0" Gutter="20">
|
||||
<hc:Col Span="16">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
<hc:Row Margin="0,20,0,0" Gutter="20">
|
||||
<hc:Col Span="8">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="8">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="4">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="4">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
<hc:Row Margin="0,20,0,0" Gutter="20">
|
||||
<hc:Col Span="4">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="16">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="4">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
<TextBlock Text="{x:Static langs:Lang.ColumnOffset}" Margin="0,32,0,0" Theme="{StaticResource TextBlockLargeBold}" HorizontalAlignment="Left" />
|
||||
<hc:Row Margin="0,20,0,0" Gutter="20">
|
||||
<hc:Col Span="6">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="6" Offset="6">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
<hc:Row Margin="0,20,0,0" Gutter="20">
|
||||
<hc:Col Span="6" Offset="6">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Span="6" Offset="6">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
<hc:Row Margin="0,20,0,0" Gutter="20">
|
||||
<hc:Col Span="12" Offset="6">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
<TextBlock Text="{x:Static langs:Lang.ResponsiveLayout}" Margin="0,32,0,0" Theme="{StaticResource TextBlockLargeBold}" HorizontalAlignment="Left" />
|
||||
<hc:Row Margin="0,20,0,0" Gutter="10">
|
||||
<hc:Col Layout="8,6,4,3,1">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Layout="4 6 8 9 11">
|
||||
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Layout="4 6 8 9 11">
|
||||
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
<hc:Col Layout="8 6 4 3 1">
|
||||
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" />
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace HandyControlDemo.UserControl;
|
||||
|
||||
public partial class GridDemo : Avalonia.Controls.UserControl, IFull
|
||||
{
|
||||
public GridDemo()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.VisualTree;
|
||||
using HandyControl.Data;
|
||||
using HandyControl.Tools.Extension;
|
||||
|
||||
namespace HandyControl.Controls;
|
||||
|
||||
public class Col : ContentControl
|
||||
{
|
||||
public static readonly StyledProperty<ColLayout?> LayoutProperty =
|
||||
AvaloniaProperty.Register<Col, ColLayout?>(nameof(Layout));
|
||||
|
||||
public ColLayout? Layout
|
||||
{
|
||||
get => GetValue(LayoutProperty);
|
||||
set => SetValue(LayoutProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<int> OffsetProperty =
|
||||
AvaloniaProperty.Register<Col, int>(nameof(Offset));
|
||||
|
||||
public int Offset
|
||||
{
|
||||
get => GetValue(OffsetProperty);
|
||||
set => SetValue(OffsetProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<int> SpanProperty =
|
||||
AvaloniaProperty.Register<Col, int>(nameof(Span), defaultValue: ColLayout.ColMaxCellCount,
|
||||
validate: v => v is >= 1 and <= ColLayout.ColMaxCellCount);
|
||||
|
||||
public int Span
|
||||
{
|
||||
get => GetValue(SpanProperty);
|
||||
set => SetValue(SpanProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<bool> IsFixedProperty =
|
||||
AvaloniaProperty.Register<Col, bool>(nameof(IsFixed));
|
||||
|
||||
public bool IsFixed
|
||||
{
|
||||
get => GetValue(IsFixedProperty);
|
||||
set => SetValue(IsFixedProperty, value);
|
||||
}
|
||||
|
||||
static Col()
|
||||
{
|
||||
LayoutProperty.Changed.AddClassHandler<Col>(InvalidateParentMeasure);
|
||||
OffsetProperty.Changed.AddClassHandler<Col>(InvalidateParentMeasure);
|
||||
SpanProperty.Changed.AddClassHandler<Col>(InvalidateParentMeasure);
|
||||
IsFixedProperty.Changed.AddClassHandler<Col>(InvalidateParentMeasure);
|
||||
}
|
||||
|
||||
private static void InvalidateParentMeasure(Col col, AvaloniaPropertyChangedEventArgs e)
|
||||
{
|
||||
if (col.GetVisualParent() is Control parent)
|
||||
{
|
||||
parent.InvalidateMeasure();
|
||||
}
|
||||
}
|
||||
|
||||
internal int GetLayoutCellCount(ColLayoutStatus status)
|
||||
{
|
||||
if (Layout is not null)
|
||||
{
|
||||
return status switch
|
||||
{
|
||||
ColLayoutStatus.Xs => Layout.Xs,
|
||||
ColLayoutStatus.Sm => Layout.Sm,
|
||||
ColLayoutStatus.Md => Layout.Md,
|
||||
ColLayoutStatus.Lg => Layout.Lg,
|
||||
ColLayoutStatus.Xl => Layout.Xl,
|
||||
ColLayoutStatus.Xxl => Layout.Xxl,
|
||||
ColLayoutStatus.Auto => 0,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(status), status, null),
|
||||
};
|
||||
}
|
||||
|
||||
if (IsFixed)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Span;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using HandyControl.Data;
|
||||
using HandyControl.Tools.Extension;
|
||||
|
||||
namespace HandyControl.Controls;
|
||||
|
||||
public class Row : Panel
|
||||
{
|
||||
private ColLayoutStatus _layoutStatus;
|
||||
|
||||
private double _maxChildDesiredHeight;
|
||||
|
||||
private double _fixedWidth;
|
||||
|
||||
public static readonly StyledProperty<double> GutterProperty =
|
||||
AvaloniaProperty.Register<Row, double>(nameof(Gutter), coerce: CoerceGutter);
|
||||
|
||||
private static double CoerceGutter(AvaloniaObject d, double value)
|
||||
=> double.IsNaN(value) || value < 0 ? 0 : value;
|
||||
|
||||
public double Gutter
|
||||
{
|
||||
get => GetValue(GutterProperty);
|
||||
set => SetValue(GutterProperty, value);
|
||||
}
|
||||
|
||||
static Row()
|
||||
{
|
||||
AffectsMeasure<Row>(GutterProperty);
|
||||
}
|
||||
|
||||
protected override Size MeasureOverride(Size constraint)
|
||||
{
|
||||
var gutter = Gutter;
|
||||
var totalCellCount = 0;
|
||||
var totalRowCount = 1;
|
||||
_fixedWidth = 0;
|
||||
_maxChildDesiredHeight = 0;
|
||||
var cols = Children.OfType<Col>().ToList();
|
||||
|
||||
foreach (var child in cols)
|
||||
{
|
||||
var cellCount = child.GetLayoutCellCount(_layoutStatus);
|
||||
if (cellCount == 0 || child.IsFixed)
|
||||
{
|
||||
child.Measure(constraint);
|
||||
_maxChildDesiredHeight = Math.Max(_maxChildDesiredHeight, child.DesiredSize.Height);
|
||||
_fixedWidth += child.DesiredSize.Width + gutter;
|
||||
}
|
||||
}
|
||||
|
||||
var itemWidth = (constraint.Width - _fixedWidth + gutter) / ColLayout.ColMaxCellCount;
|
||||
itemWidth = Math.Max(0, itemWidth);
|
||||
|
||||
foreach (var child in cols)
|
||||
{
|
||||
var cellCount = child.GetLayoutCellCount(_layoutStatus);
|
||||
if (cellCount > 0 && !child.IsFixed)
|
||||
{
|
||||
totalCellCount += cellCount;
|
||||
var availableWidth = Math.Max(0, cellCount * itemWidth - gutter);
|
||||
|
||||
child.Measure(new Size(availableWidth, constraint.Height));
|
||||
_maxChildDesiredHeight = Math.Max(_maxChildDesiredHeight, child.DesiredSize.Height);
|
||||
|
||||
if (totalCellCount > ColLayout.ColMaxCellCount)
|
||||
{
|
||||
totalCellCount = cellCount;
|
||||
totalRowCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Size(0, _maxChildDesiredHeight * totalRowCount);
|
||||
}
|
||||
|
||||
protected override Size ArrangeOverride(Size finalSize)
|
||||
{
|
||||
var gutter = Gutter;
|
||||
var totalCellCount = 0;
|
||||
var cols = Children.OfType<Col>().ToList();
|
||||
var itemWidth = (finalSize.Width - _fixedWidth + gutter) / ColLayout.ColMaxCellCount;
|
||||
itemWidth = Math.Max(0, itemWidth);
|
||||
|
||||
var childBounds = new Rect(0, 0, 0, _maxChildDesiredHeight);
|
||||
_layoutStatus = ColLayout.GetLayoutStatus(finalSize.Width);
|
||||
|
||||
foreach (var child in cols)
|
||||
{
|
||||
if (!child.IsVisible)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var cellCount = child.GetLayoutCellCount(_layoutStatus);
|
||||
totalCellCount += cellCount;
|
||||
|
||||
var childWidth = (cellCount > 0 && !child.IsFixed) ? Math.Max(0, cellCount * itemWidth - gutter) : child.DesiredSize.Width;
|
||||
childBounds = childBounds.WithWidth(childWidth);
|
||||
childBounds = childBounds.WithX(childBounds.X + child.Offset * itemWidth);
|
||||
|
||||
if (totalCellCount > ColLayout.ColMaxCellCount)
|
||||
{
|
||||
childBounds = childBounds.WithX(0);
|
||||
childBounds = childBounds.WithY(childBounds.Y + _maxChildDesiredHeight);
|
||||
totalCellCount = cellCount;
|
||||
}
|
||||
|
||||
child.Arrange(childBounds);
|
||||
childBounds = childBounds.WithX(childBounds.X + childWidth + gutter);
|
||||
}
|
||||
|
||||
return finalSize;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace HandyControl.Data;
|
||||
|
||||
public enum ColLayoutStatus
|
||||
{
|
||||
Xs,
|
||||
Sm,
|
||||
Md,
|
||||
Lg,
|
||||
Xl,
|
||||
Xxl,
|
||||
Auto
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using HandyControl.Tools.Extension;
|
||||
|
||||
namespace HandyControl.Tools.Converter;
|
||||
|
||||
public class ColLayoutConverter : TypeConverter
|
||||
{
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
|
||||
{
|
||||
return Type.GetTypeCode(sourceType) switch
|
||||
{
|
||||
TypeCode.Int16 or TypeCode.UInt16
|
||||
or TypeCode.Int32 or TypeCode.UInt32
|
||||
or TypeCode.Int64 or TypeCode.UInt64
|
||||
or TypeCode.Single or TypeCode.Double or TypeCode.Decimal
|
||||
or TypeCode.String => true,
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
|
||||
public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType)
|
||||
=> destinationType == typeof(string);
|
||||
|
||||
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
|
||||
{
|
||||
if (value == null) throw GetConvertFromException(null!);
|
||||
|
||||
return value switch
|
||||
{
|
||||
string s => ColLayout.Parse(s),
|
||||
double d => new ColLayout((int) d),
|
||||
_ => new ColLayout(System.Convert.ToInt32(value, culture))
|
||||
};
|
||||
}
|
||||
|
||||
public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType)
|
||||
{
|
||||
if (value is ColLayout layout && destinationType == typeof(string))
|
||||
{
|
||||
return layout.ToString();
|
||||
}
|
||||
throw new ArgumentException("CannotConvertType");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using HandyControl.Data;
|
||||
using HandyControl.Tools.Converter;
|
||||
|
||||
namespace HandyControl.Tools.Extension;
|
||||
|
||||
[TypeConverter(typeof(ColLayoutConverter))]
|
||||
public class ColLayout
|
||||
{
|
||||
public const int ColMaxCellCount = 24;
|
||||
|
||||
public const int HalfColMaxCellCount = 12;
|
||||
|
||||
public const int XsMaxWidth = 768;
|
||||
|
||||
public const int SmMaxWidth = 992;
|
||||
|
||||
public const int MdMaxWidth = 1200;
|
||||
|
||||
public const int LgMaxWidth = 1920;
|
||||
|
||||
public const int XlMaxWidth = 2560;
|
||||
|
||||
public int Xs { get; set; } = 24;
|
||||
|
||||
public int Sm { get; set; } = 12;
|
||||
|
||||
public int Md { get; set; } = 8;
|
||||
|
||||
public int Lg { get; set; } = 6;
|
||||
|
||||
public int Xl { get; set; } = 4;
|
||||
|
||||
public int Xxl { get; set; } = 2;
|
||||
|
||||
public ColLayout()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ColLayout(int uniformWidth)
|
||||
{
|
||||
Xs = uniformWidth;
|
||||
Sm = uniformWidth;
|
||||
Md = uniformWidth;
|
||||
Lg = uniformWidth;
|
||||
Xl = uniformWidth;
|
||||
Xxl = uniformWidth;
|
||||
}
|
||||
|
||||
public ColLayout(int xs, int sm, int md, int lg, int xl, int xxl)
|
||||
{
|
||||
Xs = xs;
|
||||
Sm = sm;
|
||||
Md = md;
|
||||
Lg = lg;
|
||||
Xl = xl;
|
||||
Xxl = xxl;
|
||||
}
|
||||
|
||||
public object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
return new ColLayout
|
||||
{
|
||||
Xs = Xs,
|
||||
Sm = Sm,
|
||||
Md = Md,
|
||||
Lg = Lg,
|
||||
Xl = Xl,
|
||||
Xxl = Xxl
|
||||
};
|
||||
}
|
||||
|
||||
public static ColLayoutStatus GetLayoutStatus(double width)
|
||||
{
|
||||
if (width < MdMaxWidth)
|
||||
{
|
||||
if (width < SmMaxWidth)
|
||||
{
|
||||
if (width < XsMaxWidth)
|
||||
{
|
||||
return ColLayoutStatus.Xs;
|
||||
}
|
||||
return ColLayoutStatus.Sm;
|
||||
}
|
||||
return ColLayoutStatus.Md;
|
||||
}
|
||||
if (width < XlMaxWidth)
|
||||
{
|
||||
if (width < LgMaxWidth)
|
||||
{
|
||||
return ColLayoutStatus.Lg;
|
||||
}
|
||||
return ColLayoutStatus.Xl;
|
||||
}
|
||||
return ColLayoutStatus.Xxl;
|
||||
}
|
||||
|
||||
public static ColLayout Parse(string s)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(s)) throw new FormatException("InvalidStringColLayout");
|
||||
|
||||
var separators = new[] { ',', ' ' };
|
||||
var tokens = s.Split(separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
var lengths = new int[6];
|
||||
var i = 0;
|
||||
foreach (var token in tokens)
|
||||
{
|
||||
if (i >= 6) throw new FormatException("InvalidStringColLayout");
|
||||
lengths[i++] = int.Parse(token, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
return i switch
|
||||
{
|
||||
1 => new ColLayout(lengths[0]),
|
||||
2 => new ColLayout { Xs = lengths[0], Sm = lengths[1] },
|
||||
3 => new ColLayout { Xs = lengths[0], Sm = lengths[1], Md = lengths[2] },
|
||||
4 => new ColLayout { Xs = lengths[0], Sm = lengths[1], Md = lengths[2], Lg = lengths[3] },
|
||||
5 => new ColLayout
|
||||
{
|
||||
Xs = lengths[0],
|
||||
Sm = lengths[1],
|
||||
Md = lengths[2],
|
||||
Lg = lengths[3],
|
||||
Xl = lengths[4]
|
||||
},
|
||||
6 => new ColLayout
|
||||
{
|
||||
Xs = lengths[0],
|
||||
Sm = lengths[1],
|
||||
Md = lengths[2],
|
||||
Lg = lengths[3],
|
||||
Xl = lengths[4],
|
||||
Xxl = lengths[5]
|
||||
},
|
||||
_ => throw new FormatException("InvalidStringColLayout")
|
||||
};
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new StringBuilder(128);
|
||||
sb.Append(Xs.ToString(CultureInfo.CurrentCulture));
|
||||
sb.Append(',');
|
||||
sb.Append(Sm.ToString(CultureInfo.CurrentCulture));
|
||||
sb.Append(',');
|
||||
sb.Append(Md.ToString(CultureInfo.CurrentCulture));
|
||||
sb.Append(',');
|
||||
sb.Append(Lg.ToString(CultureInfo.CurrentCulture));
|
||||
sb.Append(',');
|
||||
sb.Append(Xl.ToString(CultureInfo.CurrentCulture));
|
||||
sb.Append(',');
|
||||
sb.Append(Xxl.ToString(CultureInfo.CurrentCulture));
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user