英文:
How to properly bind CommandParameter in grouped CollectionView , Xamarin forms?
问题
您已经在Xamarin Forms中创建了一个分组的CollectionView。这个CollectionView包含两个按钮(一个在CollectionView的Header中,另一个在主体中)。
要解决问题,您需要在按钮的Command
属性中设置一个命令,并将GroupedItem
作为参数传递。这样,当您点击主体中的按钮时,您将能够访问与点击标题标签时相同的GroupedItem
对象。
在XAML代码中,您可以像这样设置按钮的Command
和CommandParameter
属性:
<Button
Padding="0"
BackgroundColor="Blue"
Command="{Binding BindingContext.BodyButtonCommand, Source={Reference thisPage}}"
CommandParameter="{Binding BindingContext.SelectedGroupedItem, Source={Reference thisPage}}"
HeightRequest="30"
HorizontalOptions="Start"
Text="Click"
TextColor="white"
VerticalOptions="Start" />
然后,在GroupedItemsTestViewModel
中,您可以添加一个名为SelectedGroupedItem
的属性,并在changeBody
方法中将其设置为按钮的CommandParameter
值。这将使您能够访问相应的GroupedItem
对象。
public GroupedItem SelectedGroupedItem { get; set; }
private void changeBody(object obj)
{
SelectedGroupedItem = obj as GroupedItem;
// 现在,您可以在SelectedGroupedItem中访问与点击按钮相关联的GroupedItem对象。
}
这样,当您点击主体中的按钮时,SelectedGroupedItem
属性将包含与该按钮相关联的GroupedItem
对象,就像在点击标题标签时一样。
英文:
I have created a grouped collection view in Xamarin Forms. The collection view has 2 buttons(1 label with tap gesture recognition), one in the collection view Header and another in the body.
<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="&gt;"
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>
Here is the View Model for this
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;
}
}
On clicking the label(in the header) to toggle the form(body of the collection view) visibility, the GroupedItem is passed as the object in the toggleFormVisibility(object obj) function parameter.
But On clicking the Button in the Body of the collection view the object passed is only the Details object.
Here is the GroupedItem implementation:
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];
}
}
How can I get the GroupedItem as the passed object on clicking the Button in the body just like on clicking the label in the Header?
答案1
得分: 0
You can get the GroupedItem as the passed object on clicking the Button in the body just like on clicking the label in the Header by putting the Button into GroupFooterTemplate as shown in the provided XML code. This will allow you to achieve the desired effect.
Additionally, there's another way to get the GroupedItem by making only one item in the collection view body visible at a time. When you click the Button, you can send the GroupedItem that is currently visible, which is controlled by the arrow in the header. This way, you can obtain the whole grouped item.
英文:
> How can I get the GroupedItem as the passed object on clicking the Button in the body just like on clicking the label in the Header?
You can put the Button into GroupFooterTemplate like this:
<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>
So you can get the GroupedItem as the passed object on clicking the Button. And this is the effect:
Update:
As Ashish said, in addition to the above method to get GroupedItem through GroupFooterTemplate, there is another way to achieve it:
> By making only one from item(collection view body) to be visible at a time. Now I just send the GroupedItem that is visible when I click the Button. Since the visibility is handled by the arrow in the header and hence I can get the whole grouped item.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论