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.
