C# 使用ListView执行WinRT ObservableCollection删除操作

C# 使用ListView执行WinRT ObservableCollection删除操作,c#,listview,windows-runtime,C#,Listview,Windows Runtime,我正在开发一个WinRT 8.1应用程序,在该应用程序中,我将ListView控件绑定到ObservableCollection,如下所示 <ListView x:Name="DetailsViews" HorizontalAlignment="Center" VerticalAlignment="Top" Grid.Row="3" Width="395"> <ListView.ItemTemplate>

我正在开发一个WinRT 8.1应用程序,在该应用程序中,我将
ListView
控件绑定到
ObservableCollection
,如下所示

            <ListView x:Name="DetailsViews" HorizontalAlignment="Center" VerticalAlignment="Top" Grid.Row="3" Width="395">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid x:Name="grid" Holding="grid_Holding" Height="60" Width="395">
                        <FlyoutBase.AttachedFlyout>
                            <MenuFlyout>
                                <MenuFlyoutItem x:Name="DeleteButton" Text="delete" Click="DeleteSelectedItem"/>
                            </MenuFlyout>
                        </FlyoutBase.AttachedFlyout>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="70"/>
                            <ColumnDefinition Width="1*"/>
                            <ColumnDefinition Width="40"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock HorizontalAlignment="Center" FontSize="32" TextAlignment="Center" Text="{Binding DetailTitle}" VerticalAlignment="Center"/>
                        <TextBox HorizontalAlignment="Left" FontSize="32" Height="{Binding ElementName=grid, Path=Height}" Text="{Binding DetailValue}" TextWrapping="Wrap" VerticalAlignment="Center" Grid.Column="1" Width="320"/>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

如何更新UI以及可能出现的问题?

好的,这是我能想到的最基本的例子,使用基本的空模板,它是有效的,这就是@KooKiz说您的代码看起来不错的原因

因此,您至少需要发布声明ListView的部分,以便获得有关问题的帮助

Xaml

因此,当您用手指按住时,会触发按住事件,但此事件不会选择任何项目,因为项目是在触摸/单击时选中的,这就是为什么单击“删除”时,它没有选中元素的原因

我已经测试过用单触键选择一个项目,然后做保持部分,它工作正常

解决方案

因此,现在我们知道发生了什么,根据您最终想要实现什么,有不同的解决方案,为了简单起见,我将假设最容易实现:)

假设您不以任何其他方式使用所选项目,而只是删除它们或导航(不需要选择列表视图项目)

因此,首先我们将XAML中的ListView编辑为SelectionMode=“None” (请注意,给定的修复程序在没有它的情况下可以工作,但可能会混淆用户)

然后我们需要稍微修改删除和保留处理程序以使用新属性

private void DeleteSelectedItem(object sender, RoutedEventArgs e)
{
    //items.RemoveAt(DetailsViews.SelectedIndex);
    items.Remove(SelectedItem);
}

private void grid_Holding(object sender, Windows.UI.Xaml.Input.HoldingRoutedEventArgs e)
{
    SelectedItem = (sender as FrameworkElement).DataContext as Person;
    FlyoutBase.ShowAttachedFlyout(sender as FrameworkElement);
}
所以现在它们要做的是:删除项,现在按对象删除,而不是按索引删除

并且该对象来自holding处理程序,在该处理程序中,您将所选项目设置为当前按下的元素的DataContext(即ListView元素的DataContext,即Person)

我建议您添加一些防御性编程,并进行一些检查,以防止程序崩溃/异常。此外,我建议您复习一些课程,如果您正在做的不是测试项目,那么就如何使用MVVM


干杯,快乐编码;)

我看你的代码没有问题。您在哪里呼叫
DeleteSelectedItem
?您能给我们看一下ListView的完整XAML代码吗?很抱歉,我不能在这里发布我的全部XAML代码,您能告诉我,DeleteSelectedItem应该在哪里定义吗?它不是intellisense中ListView的属性?我使用的是ObservableCollection。实际上我也在做同样的事情,但是我的ListView SelectedIndex是-1,这会导致ArgumentOutOfRangeException。有没有办法使SelectedIndex与ObservaleCollection相同?如果从列表中选择元素,可能选择模式设置为none或类似的内容。或者,如果要将所选索引绑定到某个变量,则会发生冲突。。。如果你粘贴一些代码会更容易。您可以尝试为所选索引或所选项创建一个属性(在ViewModel或代码隐藏中,如果这是您要使用的),然后使用另一个remove方法(按项),这是我在构造函数中使用的代码,它是myList=new ObservableCollection();添加(newperson(){DetailTitle=“Key”,DetailValue=“Value”});DetailsView.ItemsSource=myList;private void DeleteSelectedItem(对象发送方,RoutedEventTargets e){this.myList.RemoveAt(this.DetailsView.SelectedIndex);}很抱歉没有显示缩进的代码。@JanshairKhan这部分代码不是问题代码,如果您每次收到选定索引的-1,则问题在于您绑定数据的方式或您使用应用程序的方式(例如,如果您在按delete键之前未选择任何项目)。但是,您必须删除代码的+1部分,因为如果选择最后一个,它将导致超出范围的异常item@JanshairKhan请发布您的xaml或至少是带有ListView声明的部分,最好对您的原始答案进行编辑,以便能够比在评论中更好地格式化它
private void DeleteSelectedItem(object sender, RoutedEventArgs e)
{
    this.myList.RemoveAt(this.DetailsViews.SelectedIndex);
}
<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <ListView Name="ItemsView" ItemsSource="{Binding items}"/>
        <Button Click="Button_Click" Content="Test Remove"></Button>
    </Grid>
</Page>
using System;
using System.Collections.ObjectModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace App1
{
    public sealed partial class MainPage : Page
    {
        ObservableCollection<String> items = new ObservableCollection<string>();

        public MainPage()
        {
            this.InitializeComponent();

            items.Add("First Item");
            items.Add("Second Item");
            items.Add("Third Item");
            items.Add("Fourth Item");

            ItemsView.ItemsSource = items;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            items.RemoveAt(ItemsView.SelectedIndex);
        }
    }
}
private void grid_Holding(object sender, Windows.UI.Xaml.Input.HoldingRoutedEventArgs e)
{
    FlyoutBase.ShowAttachedFlyout(sender as FrameworkElement);
}
<ListView x:Name="DetailsViews" 
          SelectionMode="None"
          HorizontalAlignment="Center"
          VerticalAlignment="Top" 
          Grid.Row="3" 
          Width="395">
public Person SelectedItem { get; set; }
private void DeleteSelectedItem(object sender, RoutedEventArgs e)
{
    //items.RemoveAt(DetailsViews.SelectedIndex);
    items.Remove(SelectedItem);
}

private void grid_Holding(object sender, Windows.UI.Xaml.Input.HoldingRoutedEventArgs e)
{
    SelectedItem = (sender as FrameworkElement).DataContext as Person;
    FlyoutBase.ShowAttachedFlyout(sender as FrameworkElement);
}