C# 如何获取Xamarin CollectionView项的索引?

C# 如何获取Xamarin CollectionView项的索引?,c#,xaml,xamarin,collectionview,itemtemplate,C#,Xaml,Xamarin,Collectionview,Itemtemplate,我有一个集合视图: <CollectionView Grid.Row="10" Grid.Column="0" Grid.ColumnSpan="1" x:Name="SomeCollection" ItemsLayout="VerticalList"> <CollectionView.ItemTemplate> <DataTemplate&g

我有一个集合视图:

<CollectionView Grid.Row="10" Grid.Column="0" Grid.ColumnSpan="1" x:Name="SomeCollection"
        ItemsLayout="VerticalList">
<CollectionView.ItemTemplate>
    <DataTemplate>
        <StackLayout Orientation="Horizontal" Padding="3" Spacing="0">
            <Label WidthRequest="90" HeightRequest="20" Text="{Binding SomeItemText}" BackgroundColor="Black" TextColor="White"
               VerticalTextAlignment="Center" HorizontalTextAlignment="Center" />
            <Button WidthRequest="36" HeightRequest="36" CornerRadius="0" ImageSource="plus_thick.xml" BackgroundColor="Green"
                Clicked="Duplicate_Clicked" />
            <Button WidthRequest="36" HeightRequest="36" CornerRadius="0" ImageSource="close_thick.xml" BackgroundColor="Red" 
                Clicked="Remove_Clicked" />
        </StackLayout>
    </DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>

集合中的每个项目都有一个副本和一个删除按钮。通过单击按钮,我想复制/删除项目,但CollectionView没有项目索引


你能帮我做一个自定义的渲染器,或者更简单更简单的吗?

我会将按钮绑定到一个
命令,而不是使用click事件

这样,在拥有ItemsSource的ViewModel中,您只需检查作为参数传递到命令中的Item ViewModel的索引。因此,在ViewModel中添加如下内容:

public Command<ItemViewModel> RemoveItemCommand { get; }

ctor() // this is the ViewModel constructor
{
    RemoveItemCommand = new Command<ItemViewModel>(DoRemoveItemCommand);
}

private void DoRemoveItemCommand(ItemViewModel model)
{
    // do stuff to remove
    // probably something like:
    Items.Remove(model);
    // or get the index like:
    var index = Items.IndexOf(model);
}
public命令removietemcommand{get;}
ctor()//这是ViewModel构造函数
{
removietemcommand=新命令(doremovietemcommand);
}
私有void doremovietemCommand(ItemViewModel模型)
{
//做一些事情来移除
//可能是这样的:
项目。移除(模型);
//或者获得如下索引:
var指数=项目指数(模型);
}
然后可以像这样绑定此命令:

<Button
    WidthRequest="36"
    HeightRequest="36"
    CornerRadius="0"
    ImageSource="close_thick.xml"
    BackgroundColor="Red"
    Command="{Binding Source={RelativeSource AncestorType={x:Type local:ItemViewModel}}, Path=RemoveItemCommand}"
    CommandParameter="{Binding}" />

我会将按钮绑定到
命令,而不是使用单击事件

这样,在拥有ItemsSource的ViewModel中,您只需检查作为参数传递到命令中的Item ViewModel的索引。因此,在ViewModel中添加如下内容:

public Command<ItemViewModel> RemoveItemCommand { get; }

ctor() // this is the ViewModel constructor
{
    RemoveItemCommand = new Command<ItemViewModel>(DoRemoveItemCommand);
}

private void DoRemoveItemCommand(ItemViewModel model)
{
    // do stuff to remove
    // probably something like:
    Items.Remove(model);
    // or get the index like:
    var index = Items.IndexOf(model);
}
public命令removietemcommand{get;}
ctor()//这是ViewModel构造函数
{
removietemcommand=新命令(doremovietemcommand);
}
私有void doremovietemCommand(ItemViewModel模型)
{
//做一些事情来移除
//可能是这样的:
项目。移除(模型);
//或者获得如下索引:
var指数=项目指数(模型);
}
然后可以像这样绑定此命令:

<Button
    WidthRequest="36"
    HeightRequest="36"
    CornerRadius="0"
    ImageSource="close_thick.xml"
    BackgroundColor="Red"
    Command="{Binding Source={RelativeSource AncestorType={x:Type local:ItemViewModel}}, Path=RemoveItemCommand}"
    CommandParameter="{Binding}" />

关于通过按钮命令获取当前集合视图项目索引,我做了一个示例,您可以查看:

 <StackLayout>
        <CollectionView
            x:Name="SomeCollection"
            ItemsLayout="VerticalList"
            ItemsSource="{Binding items}">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout
                        Padding="3"
                        Orientation="Horizontal"
                        Spacing="0">
                        <Label
                            BackgroundColor="Black"
                            HeightRequest="20"
                            HorizontalTextAlignment="Center"
                            Text="{Binding SomeItemText}"
                            TextColor="White"
                            VerticalTextAlignment="Center"
                            WidthRequest="90" />
                        <Button
                            BackgroundColor="Green"
                            Command="{Binding BindingContext.duplicatecommand, Source={x:Reference SomeCollection}}"
                            CommandParameter="{Binding}"
                            CornerRadius="0"
                            HeightRequest="36"
                            Text="duplicate item"
                            WidthRequest="36" />
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>

 public partial class Page13 : ContentPage
{
    public ObservableCollection<someitems> items { get; set; }
    public ICommand duplicatecommand { get; set; }
    public Page13()
    {
        InitializeComponent();
        items = new ObservableCollection<someitems>()
        {
            new someitems(){SomeItemText="test 1"},
            new someitems(){SomeItemText="test 2"},
            new someitems(){SomeItemText="test 3"},
            new someitems(){SomeItemText="test 4"},
            new someitems(){SomeItemText="test 5"},
            new someitems(){SomeItemText="test 6"}
        };

        duplicatecommand = new Command<someitems>(getindexfun);
        this.BindingContext = this;
    }
    private void getindexfun(someitems item)
    {
        int index = items.IndexOf(item);
    }
}

public class someitems
{
    public string SomeItemText { get; set; }
}

公共部分类第13页:内容页
{
公共ObservableCollection项{get;set;}
公共ICommand duplicate命令{get;set;}
公共页13()
{
初始化组件();
items=新的ObservableCollection()
{
新建someitems(){SomeItemText=“测试1”},
新建someitems(){SomeItemText=“测试2”},
新建someitems(){SomeItemText=“test 3”},
新建someitems(){SomeItemText=“test 4”},
新建someitems(){SomeItemText=“test 5”},
新建someitems(){SomeItemText=“测试6”}
};
duplicatecommand=新命令(getindexfun);
this.BindingContext=this;
}
私有void getindexfun(someitems项)
{
int index=items.IndexOf(item);
}
}
公共类项目
{
公共字符串SomeItemText{get;set;}
}

关于通过按钮命令获取当前集合视图项目索引,我做了一个示例,您可以查看:

 <StackLayout>
        <CollectionView
            x:Name="SomeCollection"
            ItemsLayout="VerticalList"
            ItemsSource="{Binding items}">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <StackLayout
                        Padding="3"
                        Orientation="Horizontal"
                        Spacing="0">
                        <Label
                            BackgroundColor="Black"
                            HeightRequest="20"
                            HorizontalTextAlignment="Center"
                            Text="{Binding SomeItemText}"
                            TextColor="White"
                            VerticalTextAlignment="Center"
                            WidthRequest="90" />
                        <Button
                            BackgroundColor="Green"
                            Command="{Binding BindingContext.duplicatecommand, Source={x:Reference SomeCollection}}"
                            CommandParameter="{Binding}"
                            CornerRadius="0"
                            HeightRequest="36"
                            Text="duplicate item"
                            WidthRequest="36" />
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>

 public partial class Page13 : ContentPage
{
    public ObservableCollection<someitems> items { get; set; }
    public ICommand duplicatecommand { get; set; }
    public Page13()
    {
        InitializeComponent();
        items = new ObservableCollection<someitems>()
        {
            new someitems(){SomeItemText="test 1"},
            new someitems(){SomeItemText="test 2"},
            new someitems(){SomeItemText="test 3"},
            new someitems(){SomeItemText="test 4"},
            new someitems(){SomeItemText="test 5"},
            new someitems(){SomeItemText="test 6"}
        };

        duplicatecommand = new Command<someitems>(getindexfun);
        this.BindingContext = this;
    }
    private void getindexfun(someitems item)
    {
        int index = items.IndexOf(item);
    }
}

public class someitems
{
    public string SomeItemText { get; set; }
}

公共部分类第13页:内容页
{
公共ObservableCollection项{get;set;}
公共ICommand duplicate命令{get;set;}
公共页13()
{
初始化组件();
items=新的ObservableCollection()
{
新建someitems(){SomeItemText=“测试1”},
新建someitems(){SomeItemText=“测试2”},
新建someitems(){SomeItemText=“test 3”},
新建someitems(){SomeItemText=“test 4”},
新建someitems(){SomeItemText=“test 5”},
新建someitems(){SomeItemText=“测试6”}
};
duplicatecommand=新命令(getindexfun);
this.BindingContext=this;
}
私有void getindexfun(someitems项)
{
int index=items.IndexOf(item);
}
}
公共类项目
{
公共字符串SomeItemText{get;set;}
}

老实说,我的应用程序非常简单,直到现在我才有了ViewModel。实现后,我遇到了以下错误:在类型“BindingExtension”中找不到属性“ElementName”。删除ElementName后,button命令将不会启动。啊,是的,与WPF相比,Xamarin.Forms中的button命令有点不同。让我来解决这个问题。在这里阅读官方文档中关于相对绑定的更多信息:谢谢链接。绑定到祖先会导致“Type ItemViewModel not found in xmlns”错误,因此我必须在AssemblyInfo.cs中注释掉[assembly:XamlCompilation(XamlCompilationOptions.Compile)]行。无论我怎么尝试,按钮命令仍然不会触发。没有祖先的简单按钮可以正常工作。@Tomo请查看我的回复并重试。老实说,我的应用程序非常简单,直到现在我才有ViewModel。实现后,我遇到了以下错误:在类型“BindingExtension”中找不到属性“ElementName”。删除ElementName后,button命令将不会启动。啊,是的,与WPF相比,Xamarin.Forms中的button命令有点不同。让我来解决这个问题。在这里阅读官方文档中关于相对绑定的更多信息:谢谢链接。绑定到祖先会导致“Type ItemViewModel not found in xmlns”错误,因此我必须在AssemblyInfo.cs中注释掉[assembly:XamlCompilation(XamlCompilationOptions.Compile)]行。无论我怎么尝试,按钮命令仍然不会触发。没有祖先的简单按钮工作正常。@Tomo请查看我的回复并重试。