Я создал сгруппированное представление коллекции в Xamarin Forms. В представлении коллекции есть 2 кнопки (1 метка с распознаванием жестов касания), одна в заголовке представления коллекции, а другая в теле.
<CollectionView IsGrouped = "True" ItemsSource = "{Binding Items}">
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<ContentView Padding = "0,10,0,0">
<Grid
BackgroundColor = "Black"
ColumnDefinitions = "*,30"
HorizontalOptions = "FillAndExpand">
<Label
HorizontalOptions = "Start"
Text = "{Binding Title}"
TextColor = "White" />
<Label
BackgroundColor = "BLue"
FontAttributes = "Bold"
HorizontalOptions = "End"
HorizontalTextAlignment = "Center"
Text = ">"
TextColor = "White"
WidthRequest = "30">
<Label.GestureRecognizers>
<TapGestureRecognizer Command = "{Binding BindingContext.ToggleForm, Source = {Reference thisPage}}" CommandParameter = "{Binding .}" />
</Label.GestureRecognizers>
</Label>
</Grid>
</ContentView>
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout BackgroundColor = "Azure" IsVisible = "{Binding IsVisible}">
<Label Text = "{Binding Description}" />
<Button
Padding = "0"
BackgroundColor = "Blue"
Command = "{Binding BindingContext.BodyButtonCommand, Source = {Reference thisPage}}"
CommandParameter = "{Binding .}"
HeightRequest = "30"
HorizontalOptions = "Start"
Text = "Click"
TextColor = "white"
VerticalOptions = "Start" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Вот модель просмотра для этого
public class GroupedItemsTestViewModel
{
public ObservableCollection<GroupedItem> Items { get; set; }
public ICommand ToggleForm { get; }
public ICommand BodyButtonCommand { get; }
public GroupedItemsTestViewModel()
{
Items = new ObservableCollection<GroupedItem>()
{
new GroupedItem("Title 1",new List<Details>{ new Details() {Description = "Description 1" } }),
new GroupedItem("Title 2",new List<Details>{ new Details() {Description = "Description 2" } }),
new GroupedItem("Title 3",new List<Details>{ new Details() {Description = "Description 3" } })
};
ToggleForm = new Command(toggleFormVisibility);
BodyButtonCommand = new Command(changeBody);
}
private void toggleFormVisibility(object obj)
{
var type = obj.GetType();
var clickedObj = obj as GroupedItem;
if (clickedObj != null)
{
var form = clickedObj.Form;
form.IsVisible = form.IsVisible==true?false:true;
}
}
private void changeBody(object obj)
{
var clickedObj = obj as GroupedItem;
}
}
При щелчке метки (в заголовке), чтобы переключить видимость формы (тела представления коллекции), GroupedItem передается как объект в параметре функции toggleFormVisibility (object obj). Но при нажатии кнопки в теле представления коллекции переданный объект является только объектом Details.
Вот реализация GroupedItem:
public class GroupedItem : List<Details>
{
public string Title { get; }
public Details Form { get; }
public GroupedItem(string title, List<Details> form) : base(form)
{
Title = title;
Form = form[0];
}
}
Как я могу получить GroupedItem в качестве переданного объекта при нажатии кнопки в теле так же, как при нажатии на метку в заголовке?
Как я могу получить GroupedItem в качестве переданного объекта при нажатии кнопки в теле так же, как при нажатии на метку в заголовке?
Вы можете поместить кнопку в GroupFooterTemplate следующим образом:
<CollectionView IsGrouped = "True" ItemsSource = "{Binding Items}">
<CollectionView.GroupHeaderTemplate >
....
</CollectionView.GroupHeaderTemplate>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout BackgroundColor = "Azure" IsVisible = "{Binding IsVisible}">
<Label Text = "{Binding Description}" />
<!--<Button
Padding = "0"
BackgroundColor = "Blue"
Command = "{Binding BindingContext.BodyButtonCommand, Source = {Reference thisPage}}"
CommandParameter = "{Binding .}"
HeightRequest = "30"
HorizontalOptions = "Start"
Text = "Click"
TextColor = "white"
VerticalOptions = "Start" />-->
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.GroupFooterTemplate>
<DataTemplate>
<StackLayout >
<Button
Padding = "0"
BackgroundColor = "Blue"
Command = "{Binding BindingContext.BodyButtonCommand, Source = {Reference thisPage}}"
CommandParameter = "{Binding .}"
HeightRequest = "30"
HorizontalOptions = "Start"
Text = "Click"
TextColor = "white"
VerticalOptions = "Start" />
</StackLayout>
</DataTemplate>
</CollectionView.GroupFooterTemplate>
</CollectionView>
Таким образом, вы можете получить GroupedItem в качестве переданного объекта при нажатии кнопки. А это эффект:
Обновлять:
Как сказал Ашиш, в дополнение к описанному выше методу получения GroupedItem через GroupFooterTemplate есть еще один способ добиться этого:
Делая только один из элементов (тело представления коллекции) видимым одновременно. Теперь я просто отправляю элемент GroupedItem, который отображается, когда я нажимаю кнопку. Поскольку видимость обрабатывается стрелкой в заголовке, и, следовательно, я могу получить весь сгруппированный элемент.
@Ashish Я также пробовал много способов получить GroupedItem в теле раньше, но потерпел неудачу. Он получает только GroupedItem в верхнем или нижнем колонтитуле. Если это не повлияет на вашу другую функциональность или внешний вид, я предлагаю вам разместить GroupedItem в нижнем колонтитуле.
да тут же. Я только что сделал обходной путь, сделав видимым только один из элементов (тело представления коллекции) за раз. Теперь я просто отправляю элемент GroupedItem, который отображается, когда я нажимаю кнопку. Поскольку видимость обрабатывается стрелкой в заголовке, и, следовательно, я могу получить весь сгруппированный элемент. Немного дергано, но пока работает ;).
@ Ашиш, я тебя понимаю. Это действительно метод👍. И я обновил ответ на основе того, что вы сказали.
Эй, спасибо за предложение. Но мне нужно, чтобы кнопка находилась в теле представления коллекции, а не в нижнем колонтитуле. На корпусе есть и другие компоненты, и эта кнопка — одна из них. Для лучшей справки тело содержит сведения о человеке, а кнопка (согласно дизайну) должна быть в теле, и при ее нажатии она должна отправлять объект (GroupedItem) на следующую страницу.