I have a collection of objects inside Grid
. Each object is displayed within a Border
. What I need is to each Border
- tile to take all available horizontal space. Right now I have a set of rectangles of various shapes and sizes which doesn't look really good.
This is content definition:
Content = new AbsoluteLayout
{
Children =
{
new ScrollView
{
Content = new Grid
{
Children =
{
collectionView
.Bind(ItemsView.ItemsSourceProperty, nameof(_viewModel.Notifications))
}
}
},
buttonCorner.Text("New")
.LayoutBounds(1, 1, -1, -1).LayoutFlags(AbsoluteLayoutFlags.PositionProportional)
}
}.BackgroundColor(Colors.Snow).Margin(20);
This is definition of the CollectionView
var collectionView = new CollectionView();
collectionView.ItemTemplate = new DataTemplate(() =>
{
var border = new Border
{
Stroke = Colors.LightGray,
StrokeThickness = 1,
StrokeShape = new RoundRectangle { CornerRadius = 10 },
BackgroundColor = Colors.White//,
//HorizontalOptions = LayoutOptions.FillAndExpand //deprecated, doesn't do anything
};
var grid = new Grid
{
Padding = 10,
RowDefinitions = new RowDefinitionCollection
{
new RowDefinition(GridLength.Auto),
new RowDefinition(GridLength.Auto)
},
ColumnDefinitions = new ColumnDefinitionCollection
{
new ColumnDefinition(GridLength.Auto),
new ColumnDefinition(GridLength.Auto)
}
};
var titleLabel = new Label
{
FontAttributes = FontAttributes.Bold,
FontSize = 18,
TextColor = Colors.Black
};
titleLabel.SetBinding(Label.TextProperty, "Title");
var descriptionLabel = new Label
{
FontSize = 14,
TextColor = Colors.Gray
};
descriptionLabel.SetBinding(Label.TextProperty, "Description");
var buttonDelete = new Button
{
Text = "Delete",
BackgroundColor = Colors.Red,
TextColor = Colors.White,
Padding = 5,
FontSize = 12,
};
buttonDelete.Clicked += async (sender, e) =>
{
if (sender is Button btn && btn.BindingContext is Notification notification)
{
await _viewModel.Delete(notification.Id);
await _viewModel.Initialize();
}
};
buttonDelete.SetBinding(BindableObject.BindingContextProperty, ".");
grid.Add(titleLabel, 0, 0);
grid.Add(descriptionLabel, 0, 1);
grid.Add(buttonDelete, 1, 0);
border.Content = grid;
return border;
});
collectionView.ItemsLayout = new GridItemsLayout(1, ItemsLayoutOrientation.Vertical)
{
Span = 1 //doesn't do anything
};
I'm out of ideas. Everything either does nothing or triggers errors/warnings. LayoutOptions.Fill
doesn't do anything either.
If no one here knows how to fix it, I will have to switch to XAML markup, C# markup lacks necessary documentation.
I have a collection of objects inside Grid
. Each object is displayed within a Border
. What I need is to each Border
- tile to take all available horizontal space. Right now I have a set of rectangles of various shapes and sizes which doesn't look really good.
This is content definition:
Content = new AbsoluteLayout
{
Children =
{
new ScrollView
{
Content = new Grid
{
Children =
{
collectionView
.Bind(ItemsView.ItemsSourceProperty, nameof(_viewModel.Notifications))
}
}
},
buttonCorner.Text("New")
.LayoutBounds(1, 1, -1, -1).LayoutFlags(AbsoluteLayoutFlags.PositionProportional)
}
}.BackgroundColor(Colors.Snow).Margin(20);
This is definition of the CollectionView
var collectionView = new CollectionView();
collectionView.ItemTemplate = new DataTemplate(() =>
{
var border = new Border
{
Stroke = Colors.LightGray,
StrokeThickness = 1,
StrokeShape = new RoundRectangle { CornerRadius = 10 },
BackgroundColor = Colors.White//,
//HorizontalOptions = LayoutOptions.FillAndExpand //deprecated, doesn't do anything
};
var grid = new Grid
{
Padding = 10,
RowDefinitions = new RowDefinitionCollection
{
new RowDefinition(GridLength.Auto),
new RowDefinition(GridLength.Auto)
},
ColumnDefinitions = new ColumnDefinitionCollection
{
new ColumnDefinition(GridLength.Auto),
new ColumnDefinition(GridLength.Auto)
}
};
var titleLabel = new Label
{
FontAttributes = FontAttributes.Bold,
FontSize = 18,
TextColor = Colors.Black
};
titleLabel.SetBinding(Label.TextProperty, "Title");
var descriptionLabel = new Label
{
FontSize = 14,
TextColor = Colors.Gray
};
descriptionLabel.SetBinding(Label.TextProperty, "Description");
var buttonDelete = new Button
{
Text = "Delete",
BackgroundColor = Colors.Red,
TextColor = Colors.White,
Padding = 5,
FontSize = 12,
};
buttonDelete.Clicked += async (sender, e) =>
{
if (sender is Button btn && btn.BindingContext is Notification notification)
{
await _viewModel.Delete(notification.Id);
await _viewModel.Initialize();
}
};
buttonDelete.SetBinding(BindableObject.BindingContextProperty, ".");
grid.Add(titleLabel, 0, 0);
grid.Add(descriptionLabel, 0, 1);
grid.Add(buttonDelete, 1, 0);
border.Content = grid;
return border;
});
collectionView.ItemsLayout = new GridItemsLayout(1, ItemsLayoutOrientation.Vertical)
{
Span = 1 //doesn't do anything
};
I'm out of ideas. Everything either does nothing or triggers errors/warnings. LayoutOptions.Fill
doesn't do anything either.
If no one here knows how to fix it, I will have to switch to XAML markup, C# markup lacks necessary documentation.
The outer ScrollView
is placed inside the AbsoluteLayout
but you don't set the size limit of the ScrollView
. If you set the HorizontalOption
of Border
which is inside the ScrollView
to LayoutOptions.Fill, it may not know how much space it should take.
You may try defining the size of ScrollView
in the AbsoluteLayout
since it is the child element of AbsoluteLayout, e.g.
new ScrollView
{
Content = new Grid
{
Children =
{
collectionView
.Bind(ItemsView.ItemsSourceProperty, nameof(_viewModel.Notifications))
}
}
}.LayoutBounds(-1, -1, 1, 1).LayoutFlags(AbsoluteLayoutFlags.SizeProportional)
The above code use proportional values to define the size of ScrollView
to fill the whole space. Then the Border should fill all Horizontal space when using LayoutOptions.Fill
. For more info about AbsoluteLayoutFlags, please refer to Proportional positioning and sizing
Please let me know if you have any question.