使用ListView进行WinRT ObservableCollection删除操作

时间:2015-10-25 08:16:41

标签: c# listview windows-runtime

我正在开发一个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>

这是我的代码隐藏文件。

myList = new ObservableCollection<Person>();

myList.Add(new Person() { DetailTitle = "Key", DetailValue = "Value"  });

DetailsViews.ItemsSource = myList;

我需要知道,如何从ObservableCollection删除项目,以便在每次删除时更新UI。这是我的删除代码,但它不起作用,因为SelectedIndex每次返回-1,如果我在那里放置一个断点。

private void DeleteSelectedItem(object sender, RoutedEventArgs e)
{
    this.myList.RemoveAt(this.DetailsViews.SelectedIndex);
}

如何更新用户界面以及可能出现的问题?

1 个答案:

答案 0 :(得分:1)

好的,这是我用基本的空模板可以想到的最基本的例子,它可以工作,这就是@KooKiz说你的代码看起来没问题的原因。

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

的Xaml

<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);
        }
    }
}

修改

好的,感谢你的代码更新,我能够找到它的错误,我有一个快速的解决方案,如果它不是你想要它的一些建议:)

<强>解释

我想你有一个处理hold事件的方法,如下所示:

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

所以会发生什么是您在用手指按住时触发保持事件但此事件未选择任何项目,因为项目是在触摸/点击时选择的,这就是为什么当您点击删除它时没有选定元素。

我已经测试过选择一个单项触摸的项目,然后执行保持部分并且它正常工作。

解决方案

现在我们知道发生了什么,根据你想要在最后实现的目标有不同的解决方案,为简单起见,我认为最容易实现:)。

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

首先,我们将XAML中的ListView编辑为 SelectionMode =“无” (请注意,给定的修复程序在没有它的情况下工作但可能会使用户感到困惑)

<ListView x:Name="DetailsViews" 
          SelectionMode="None"
          HorizontalAlignment="Center"
          VerticalAlignment="Top" 
          Grid.Row="3" 
          Width="395">

然后你需要在你的代码中添加一个属性来保存所选项的值,因为你不会使用ListView的选择(索引或项)。

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);
}

所以这些现在做的是:删除项目现在由对象而不是索引删除

对象来自保持处理程序,您将所选项目设置为当前按下元素的DataContext(这是ListView元素的DataContext,即Person)

我建议你添加一些防御性编程并做一些检查以防止程序崩溃/异常。另外,如果你做的不是测试项目,我建议你去学习一些关于如何使用MVVM的课程。

干杯和快乐的编码;)