通过单击 ListView (Xamarin.Forms) 中的按钮获取当前项目

eve*_*ert 10 c# xamarin.forms

我有以下列表视图(项目源设置在外部和字符串列表):

<?xml version="1.0" encoding="utf-8" ?>
<ListView xmlns="http://xamarin.com/schemas/2014/forms"
          xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
          x:Class="XXX.EditItemsList">

    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout>
                    <Label Text="{Binding .}"/>
                    <Button Text="Delete"/>
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>

</ListView>
Run Code Online (Sandbox Code Playgroud)

通过单击按钮,我想删除列表中的当前项目(字符串)。这怎么可能?

谢谢你的帮助 :)

Dec*_*oth 9

原则上,我认为@Krzysztof Skowronek 给出的答案是正确的,我将尝试对其进行详细说明,并避免使用 ViewModel,因为您似乎没有使用它(尽管使用它是 Xamarin Forms 上的最佳实践) )。

按照您自己的代码,我在 XAML 中编写了以下代码:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DeleteButton"
             x:Class="DeleteButton.MainPage">

    <ListView x:Name="listView"
              HasUnevenRows="True">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout>
                        <Label Text="{Binding .}"/>
                        <Button Text="Delete" Clicked="Delete"/>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>    
</ContentPage>
Run Code Online (Sandbox Code Playgroud)

关于解决方案的这一部分,我将给出以下评论:

  • 请注意在 XAML 顶部使用 ConntentPage 而不是 ListView,这是故意的吗?

  • 然后,注意在 ListView 上添加的 x:Name。它将用于从后面的代码中与 ListView 通信。

  • 另外请注意 HasUnevenRows 的使用设置为 True。这会导致 ListView 自动调整行的高度。

  • 最后看到在 Button 中,我将事件 Clicked 设置为“Delete”,这是您将看到的后面代码中事件处理程序的名称。

在后面的代码上我写道:

using System;
using System.Collections.ObjectModel;
using Xamarin.Forms;

namespace DeleteButton
{
    public partial class MainPage : ContentPage
    {
        ObservableCollection<String> list;

        public MainPage()
        {
            InitializeComponent();
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();

            list = new ObservableCollection<string>()
            {
                "Task 1", "Task 2", "Task 3", "Task 4", "Task 5",
                "Task 6", "Task 7", "Task 8", "Task 9", "Task 10"                    
            };

            listView.ItemsSource = list;
        }

        public void Delete(Object Sender, EventArgs args)
        {
            Button button = (Button)Sender;
            StackLayout listViewItem = (StackLayout)button.Parent;
            Label label = (Label)listViewItem.Children[0];

            String text = label.Text;

            list.Remove(text);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我将字符串列表定义为 ObservableCollection(ObservableCollection 会导致 ListView 在每次更改时收到通知,以便 ListView 更新其内容,有关更多详细信息,请参阅文档)。

然后我将 ListView 的 ItemSource 属性设置为字符串集合,正如您已经完成的那样。

最后是 XAML 中的 EventHandler Delete,它由按钮上的 Click 事件调用。这里的算法非常简单:

首先,发送者被转换为一个 Button(我们知道触发事件的对象是一个 Button)。

然后我们沿着层次树向上走,直到包含 Button 和 Label 的 StackLayout 并检索它的第一个孩子,我们知道它是 Label。

获得 Label 后,我们将检索其 Text 属性并调用集合的 Remove 方法以获取该项目。

就是这样。

注意:如果我自己实现这个功能,我宁愿定义一个包含 Text 属性和 Id 属性的对象集合,以便准确地删除被点击的元素。在上面的代码中,如果集合包含两个相同的字符串,则 EventHandler 将仅针对第一次出现。

我希望这可以帮助您找到解决问题的正确方法。


sme*_*sme 8

如果不想使用命令,可以使用按钮的 Clicked 事件。IE,

<Button Text="Delete" Clicked="HandleDeleteButtonClicked" />
Run Code Online (Sandbox Code Playgroud)

然后在你的代码隐藏文件中,

private void HandleDeleteButtonClicked(object sender, EventArgs e)
{
    // Assuming your list ItemsSource is a list of strings
    // (If its a list of some other type of object, just change the type in the (cast)):
    var stringInThisCell = (string)((Button)sender).BindingContext;

    // Now you can delete stringInThisCell from your list.
    myList.Remove(stringInThisCell);
}
Run Code Online (Sandbox Code Playgroud)


Jay*_*ker 7

如果我们愿意保留 MVVM 方法,那么在您的视图中,命名 ContentPage(或任何存在的根元素)并将其用作 Source 来绑定命令:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="canaraydash.View.InviteListPage"
   x:Name="InvitesView">

   <ListView x:Class="XXX.EditItemsList">
      <ListView.ItemTemplate>
         <DataTemplate>
            <ViewCell>
               <StackLayout>
                  <Label Text="{Binding .}" />
                  <Button Text="Delete"
                   Command="{Binding Path=BindingContext.AcceptRequestCommand, Source={x:Reference InvitesView}}"
                   CommandParameter="{Binding .}" />
               </StackLayout>
            </ViewCell>
         </DataTemplate>
      </ListView.ItemTemplate>
   </ListView>
</ContentPage>
Run Code Online (Sandbox Code Playgroud)

并在您的 ViewModel 中,定义“AcceptRequestCommand”命令!