I need to create a header with multiselect options as you can see in the below image, the problem is i know how to create a multiselect list with grouping but i am not able get such options in horizontal layout and this options are dynamic as per the data passed they should get create and user can select and deselect this options on clicking can any one tell me what approach should i use or how can i achieve such functionality
Asked
Active
Viewed 125 times
0
-
Did you solved your problem or tried my solution? – nevermore Mar 19 '19 at 05:34
-
yes @JackHua-MSFT worked like charm now m just trying put all those binding stuff together – Ronak Shetiya Mar 19 '19 at 05:38
1 Answers
1
Solution:
You can use listview + custom wraplayout
to achieve your requirement.
I take the layout code from this thread:
Create new subclass which derives from Layout:
Override OnMeasure to return the size of this layout .
Override LayoutChildren to determine positions and sizes of the children.
Create Bindable Properties to personalize the use on each need.
Custom Layout:
public class WrapLayout : Layout<View>
{
public static readonly BindableProperty SpacingProperty =
BindableProperty.Create
(
"Spacing",
typeof(double),
typeof(WrapLayout),
10.0,
propertyChanged: (bindable, oldvalue, newvalue) => ((WrapLayout)bindable).OnSizeChanged()
);
public double Spacing
{
get { return (double)GetValue(SpacingProperty); }
set { SetValue(SpacingProperty, value); }
}
private void OnSizeChanged()
{
this.ForceLayout();
}
protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
{
if (WidthRequest > 0)
widthConstraint = Math.Min(widthConstraint, WidthRequest);
if (HeightRequest > 0)
heightConstraint = Math.Min(heightConstraint, HeightRequest);
double internalWidth = double.IsPositiveInfinity(widthConstraint) ? double.PositiveInfinity : Math.Max(0, widthConstraint);
double internalHeight = double.IsPositiveInfinity(heightConstraint) ? double.PositiveInfinity : Math.Max(0, heightConstraint);
return DoHorizontalMeasure(internalWidth, internalHeight);
}
private SizeRequest DoHorizontalMeasure(double widthConstraint, double heightConstraint)
{
int rowCount = 1;
double width = 0;
double height = 0;
double minWidth = 0;
double minHeight = 0;
double widthUsed = 0;
foreach (var item in Children)
{
var size = item.Measure(widthConstraint, heightConstraint);
height = Math.Max(height, size.Request.Height);
var newWidth = width + size.Request.Width + Spacing;
if (newWidth > widthConstraint)
{
rowCount++;
widthUsed = Math.Max(width, widthUsed);
width = size.Request.Width;
}
else
width = newWidth;
minHeight = Math.Max(minHeight, size.Minimum.Height);
minWidth = Math.Max(minWidth, size.Minimum.Width);
}
if (rowCount > 1)
{
width = Math.Max(width, widthUsed);
height = (height + Spacing) * rowCount - Spacing; // via MitchMilam
}
return new SizeRequest(new Size(width, height), new Size(minWidth, minHeight));
}
protected override void LayoutChildren(double x, double y, double width, double height)
{
double rowHeight = 0;
double yPos = y, xPos = x;
foreach (var child in Children.Where(c => c.IsVisible))
{
var request = child.Measure(width, height);
double childWidth = request.Request.Width;
double childHeight = request.Request.Height;
rowHeight = Math.Max(rowHeight, childHeight);
if (xPos + childWidth > width)
{
xPos = x;
yPos += rowHeight + Spacing;
rowHeight = 0;
}
var region = new Rectangle(xPos, yPos, childWidth, childHeight);
LayoutChildIntoBoundingRegion(child, region);
xPos += region.Width + Spacing;
}
}
}
And in your xaml
, use listView
with layouted buttons in viewcell
:
<ListView x:Name="EmployeeView" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<StackLayout BackgroundColor="LightBlue" Orientation="Horizontal">
<Label Text="qwewqe" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"></Label>
<Button Text="save" HorizontalOptions="EndAndExpand"></Button>
</StackLayout>
<StackLayout>
<local:WrapLayout Spacing="5">
<Button Text=" self " BackgroundColor="Red"/>
<Button Text=" mother " BackgroundColor="Green"/>
<Button Text=" father " BackgroundColor="Gray"/>
<Button Text=" grandmother " BackgroundColor="Blue"/>
<Button Text=" sister " BackgroundColor="Orange"/>
<Button Text=" brother " BackgroundColor="Aqua"/>
<Button Text=" self " BackgroundColor="Yellow"/>
<Button Text=" grandfather " BackgroundColor="Pink"/>
</local:WrapLayout>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Remember to set the dataSource
of listview and you can have a look at the result:
You could change the layout in my ViewCell to make it looks better. Try and let me if it meet your requirement?

nevermore
- 15,432
- 1
- 12
- 30