如何从 Xamarin Forms 的 ListView 中删除项目?

7

我正在尝试从ListView中删除项目/行,但困难在于我还需要传递一些委托或触发某些事件之类的东西,因此当人们点击按钮以删除该行时,我的代码会处理其他逻辑(例如从数据库中删除该项等)。

我有一个自定义控件:

public class SportsTeam : StackLayout { .. }

在这个控件中,其中一个元素是一个ListView,它列出了运动队中的所有人。

var viewModel = teamMembers.Select(x => new SportsTeamViewModel(x));

return new ListView
{
    HasUnevenRows = true,
    ItemSource = viewModel,
    ItemTemplate = new DataTemplate(typeof(SportsTeamViewCell)); 
};

SportsTeamViewCell 中,我有以下内容:

private Grid CreateContent()
{
    var grid = new Grid();
    // Setup row and column definitions.
    // Add items to the Grid 
    grid.Children.Add(...);

    var removeButton = RemoveButton;
    grid.Children.Add(removeButton);
    Grid.SetRowSpan(removeButton, 2);

    return grid;
}

private Button RemoveButton
{
    get
    {
        var button = new Button
        {
            Image = "Icons/remove.png"
        };

        return button;
    }
}

从这里开始,我不知道如何使按钮触发事件或通过构造函数传递一些删除内容,以便对要删除的单元格/行/项执行一些自定义逻辑。


将要删除的行的ID传递到RemoveButton的click事件处理程序中。 - Rohit Vipin Mathews
我该如何找到要删除的行的ID?或者每一行都可以有另一个特殊的ID,我可以给它吗?比如一些隐藏的神奇ID?或者来自绑定数据的其他值?例如IdUserName或其他任何东西... - Pure.Krome
是的,你必须使用Bindings,并将你的模型Id属性绑定到按钮的click事件。 - Rohit Vipin Mathews
3个回答

9
以下是您可以做的事情:
这是我的模型类:
public class Item  
{  
   public string ItemName { get; set; }  
   public string ItemDetails { get; set; }  
}  

在我的XAML中,或者您也可以在代码中编写,将其绑定到您的项模板的Command Parameter
<Button Text="Delete" CommandParameter="{Binding ItemName}" Clicked="DeleteClicked"></Button>

完整的项目模板将如下所示:
<ListView.ItemTemplate>  
            <DataTemplate>  
               <ViewCell>  
                  <ViewCell.View>  
                     <StackLayout Orientation="Horizontal">  
                        <Label Text="{Binding ItemName}" HorizontalOptions="StartAndExpand" FontSize="30"></Label>  
                        <Button Text="Delete" CommandParameter="{Binding ItemName}" Clicked="DeleteClicked">        
                        </Button>  
                     </StackLayout>  
                  </ViewCell.View>  
               </ViewCell>  
            </DataTemplate>  
         </ListView.ItemTemplate>    

在你的代码文件中,你可以这样做:
public void DeleteClicked(object sender, EventArgs e)  
{  
   var item = (Xamarin.Forms.Button)sender;  
   Item listitem = (from itm in allItems 
                    where itm.ItemName == item.CommandParameter.ToString() 
                    select itm)
                   .FirstOrDefault<Item>();  
   allItems.Remove(listitem);  
}  

重要提示:这只会从绑定的集合中删除该项,如果要从原始列表中删除它,则需要使用ObservableCollection

下面是所述情况的完整源代码 - 在XAMARIN.FORMS中使用Listview处理子控件事件

此外,教程 - 如何在自定义ListView中处理行选择和删除按钮也解释了从listview中删除的方法。


太棒了@Rohit!这就是我真正希望得到的答案 :) 我今天稍后会试试这段代码。谢谢伙计! - Pure.Krome
嗨@rohit - 我已经试着运行了你的代码,但是我似乎无法理解它。首先,我得到了CommandParameter。好的。其次,我不想将Clicked的代码放在我的控件内部。这是因为我不知道这个通用控件被点击后会做什么。我想要将要处理的方法传递给这个控件,以便在点击时处理。所以逻辑保持在这个控件之外 :) - Pure.Krome
如果你想让逻辑在外部,你可以使用MessagingCenter订阅点击事件,或者尝试使用.NET事件处理程序自己附加到事件。 - Rohit Vipin Mathews
我正在尝试将事件附加到我的列表视图...这就是我卡住的地方。列表视图采用ItemTemplate = new DataTemplate(typeof(SportsTeamViewCell));模板。我不知道如何(或在哪里)附加我的自定义事件...??? - Pure.Krome
如果您正在尝试在控制器和视图模型之间获取事件,请查看 Xamarin 消息中心。 - Rohit Vipin Mathews
显示剩余3条评论

3
我发现了一种类似的方法,想要分享给大家。我使用了一个ObservableCollection<MyObject>来填充列表。然后我只是用CommandParameter="{Binding .}" 来填充命令参数。这样我就得到了整个对象。然后你可以将CommandParameter强制转换为你的对象,并从ObservableCollection<MyObject>列表中删除它。
XAML:
CommandParameter="{Binding .}"

填充我的列表:

savingExpensesCollection = new ObservableCollection<SavingsExpensesEntry> ();
savingExpensesCollection .Add (new SavingsExpensesEntry ("1000 mAh Akku", "Dampfgarten", new DateTime (635808692400000000), 8.95));
savingExpensesCollection .Add (new SavingsExpensesEntry ("Cool-Mint Aroma", "Dampfgarten", new DateTime (635808692400000000), 3.95));
savingExpensesCollection .Add (new SavingsExpensesEntry ("Basis", "Dampfgarten", new DateTime (635808692400000000), 13.65));

savingExpensesList.ItemsSource = savingExpenses;

事件处理程序:

void OnDelete(object sender, EventArgs e)
{
    var menuItem = ((MenuItem)sender);
    SavingsExpensesEntry see ((SavingsExpensesEntry)menuItem.CommandParameter);
    savingExpensesCollection .Remove (see);
}

我一直在使用MenuItem,但对于Button的处理方式相同。


-1

我刚刚使用了删除按钮

  public void OnDelete(object sender, EventArgs e)
    {
        var mi = ((MenuItem)sender);

        PhotoViewModel photo= ((photoViewModel)mi.CommandParameter);
        photoModel.Remove(photo);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接