我有以下列表视图(项目源设置在外部和字符串列表):
<?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)
通过单击按钮,我想删除列表中的当前项目(字符串)。这怎么可能?
谢谢你的帮助 :)
原则上,我认为@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 将仅针对第一次出现。
我希望这可以帮助您找到解决问题的正确方法。
如果不想使用命令,可以使用按钮的 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)
如果我们愿意保留 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”命令!
| 归档时间: |
|
| 查看次数: |
14271 次 |
| 最近记录: |