【问题标题】:Deleting all items from listview从列表视图中删除所有项目
【发布时间】:2017-12-22 16:05:29
【问题描述】:

Visual Studio 新手,尝试将我使用另一种语言的 VM 部署 GUI 转换为 wpf 应用程序。我已经完成了 80%,只有几个问题。 GUI 有许多输入字段供用户填写。单击按钮时,这些输入字段会填充列表视图。 listview 是这样声明的:

<ListView x:Name="lstOut" ScrollViewer.HorizontalScrollBarVisibility="Visible" HorizontalAlignment="Left" Height="205" Margin="10,394,0,0" VerticalAlignment="Top" Width="1294"  
          ItemsSource="{Binding MyItems}" SelectionMode="Single">
<ListView.View>
    <GridView>
        <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
        <GridViewColumn Header="CPU" DisplayMemberBinding="{Binding CPU}"/>
        <GridViewColumn Header="RAM" DisplayMemberBinding="{Binding RAM}"/>
        <GridViewColumn Header="IP Address" DisplayMemberBinding="{Binding IP}"/>
        <GridViewColumn Header="Subnet" DisplayMemberBinding="{Binding Subnet}"/>
        <GridViewColumn Header="Port Group" DisplayMemberBinding="{Binding PortGroup}"/>
        <GridViewColumn Header="Gateway" DisplayMemberBinding="{Binding Gateway}"/>
        <GridViewColumn Header="DNS" DisplayMemberBinding="{Binding DNS}"/>
        <GridViewColumn Header="Description" DisplayMemberBinding="{Binding Description}"/>
        <GridViewColumn Header="Template" DisplayMemberBinding="{Binding Template}"/>
        <GridViewColumn Header="Host" DisplayMemberBinding="{Binding Host}"/>
        <GridViewColumn Header="Site Code" DisplayMemberBinding="{Binding Site}"/>
        <GridViewColumn Header="Folder" DisplayMemberBinding="{Binding Folder}"/>
        <GridViewColumn Header="DataStore" DisplayMemberBinding="{Binding Datastore}"/>
        <GridViewColumn Header="Patch Method" DisplayMemberBinding="{Binding Patch}"/>
        <GridViewColumn Header="HDD1 Size" DisplayMemberBinding="{Binding HDD1Size}"/>
        <GridViewColumn Header="HDD1 Format" DisplayMemberBinding="{Binding HDD1Format}"/>
        <GridViewColumn Header="HDD2 Size" DisplayMemberBinding="{Binding HDD2Size}"/>
        <GridViewColumn Header="HDD2 Format" DisplayMemberBinding="{Binding HDD2Format}"/>
        <GridViewColumn Header="HDD3 Size" DisplayMemberBinding="{Binding HDD3Size}"/>
        <GridViewColumn Header="HDD3 Format" DisplayMemberBinding="{Binding HDD3Format}"/>
        <GridViewColumn Header="HDD4 Size" DisplayMemberBinding="{Binding HDD4Size}"/>
        <GridViewColumn Header="HDD4 Format" DisplayMemberBinding="{Binding HDD4Format}"/>
        <GridViewColumn Header="HDD5 Size" DisplayMemberBinding="{Binding HDD5Size}"/>
        <GridViewColumn Header="HDD5 Format" DisplayMemberBinding="{Binding HDD5Format}"/>
    </GridView>
</ListView.View>

为了将 GUI 中的项目集合添加到列表视图,以及稍后在代码中导出到 csv,我声明了一个这样的集合:

public ObservableCollection<MyItem> MyItems { get; set; } = new ObservableCollection<MyItem>();

我能够以这种方式从列表视图中删除选定的项目,这似乎运作良好:

private void DeleteRow(object sender, RoutedEventArgs e)
{
    MyItem line = lstOut.SelectedItem as MyItem;
    if (line != null)
        MyItems.Remove(line);
}

我坚持的(其中一件事)是从列表视图中删除所有内容。这两种方法我都试过了:

lstOut.Items.Clear();
lstOut.Items.Remove(MyItems);

但是,当使用 ItemsSource 时,无论哪种方式都会出现错误,这是无效的。我尝试了 lstOut.ItemsSource,但找不到清除所有内容的方法。

我最终这样做了,这似乎可行(勉强):

for (int i=0; i < lstOut.Items.Count; i++)
{
    MyItems.Remove(MyItems[i]);
}

这种方法的问题是每次单击按钮都会删除一半的项目计数。如果我在列表视图中有 9 个项目,它会将其减少为 4,再次单击将其减少为 2,然后是 1,最后删除。

谁能建议一种更简单的方法来一次删除所有内容?我确信这是我想念的一些愚蠢的简单事情,但如果有任何建议,我将不胜感激。

【问题讨论】:

  • 你需要清除它绑定的集合。
  • MyItems.Clear()
  • @ASh 这是一个答案
  • 这是绑定背后的全部概念。显示和数据模型分离。不要对 GUI 元素进行操作,操作它背后的数据模型。
  • @Paparazzi,不是真正的答案,它是一种远程智能感知

标签: c# wpf listview observablecollection


【解决方案1】:

一般ICollection&lt;T&gt;,特别是ObservableCollection有方法Clear()

所以正确的方法(也是遵循 MVVM 的唯一方法)是

MyItems.Clear();

将 Clear 与 ObservableCollection 一起使用比多次调用 Remove 更有效,因为 ObservableCollection 在添加/删除/替换内部项目时会引发通知。一个关于清除的通知比许多关于删除的通知要快


为什么这段代码行为怪异?

for (int i = 0; i < lstOut.Items.Count; i++)
{
    MyItems.Remove(MyItems[i]);
}

假设初始状态是[1,2,3,4], i = 0, lstOut.Items.Count = 4

第一次迭代后变为 [2,3,4], i = 1, lstOut.Items.Count = 3

所以 i 指向项目 3

项目2 被跳过!

应该反转正确的循环(从集合中的最后一项到第一项)

for (int i = MyItems.Count - 1; i >= 0; i--)
{
    MyItems.RemoveAt(i);
}

或者另一种方法是删除 0 位置的项目,而那里的项目:

while(MyItems.Count > 0)
{
    MyItems.RemoveAt(0);
}

【讨论】:

  • 非常感谢您提供的信息。仍在从更加程序化的背景中学习。
  • @JLogan3o13,.net 是一个非常丰富的框架,这意味着很多特性和功能已经实现,只是发现它们的问题。如果我的回答有帮助,请将其标记为已接受
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-30
  • 2019-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多