WPF [SOLVED]: Deleting all items from listview

WPF [SOLVED]: Deleting all items from listview

Home Forums Frameworks WPF WPF [SOLVED]: Deleting all items from listview

Viewing 2 posts - 1 through 2 (of 2 total)
  • Author
    Posts
  • #246859

    Cloudy Point
    Keymaster

    QuestionQuestion

    New to Visual Studio, trying to convert a VM deployment GUI I have in another language to a wpf application. I am 80% of the way there, just a couple of questions. The GUI has a number of input fields for the user to fill out. The when a button is clicked those input fields populate a listview. The listview is declared like so:

    <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>
    

    For adding the collection of items from the GUI to the listview, as well as exporting to csv later in the code, I declared a collection like so:

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

    I am able to delete a selected item from the listview in this manner, which seems to work well:

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

    What I am stuck on (one of the things anyway), is deleting everything from the listview. I tried both of these methods:

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

    But get an error either way that this is not valid when ItemsSource is in use. I tried lstOut.ItemsSource, but could not find a way to clear all content.

    I ended up doing it like this, which seems to work (marginally):

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

    The problem with this method is that is removes half the item count with each button click. If I have 9 items in the listview it cuts it down to 4, another click cuts it down to 2, then 1, then finally deletes.

    Can anyone suggest an easier way to delete all content in one action? I am sure it is something stupid simple I am missing, but would appreciate any suggestions.

    #246860

    Cloudy Point
    Keymaster

    Accepted AnswerAnswer

    ICollection<T> in general and ObservableCollection in particular have method Clear()

    so the correct way (and the only way when you follow MVVM) is

    MyItems.Clear();
    

    using Clear with ObservableCollection is much more effective than multiple calls to Remove, because ObservableCollection raises notifications when items inside are added/removed/replaced. One notification about Clear is faster than numerous notifications about Remove


    why this code acts weirdly?

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

    let’s say initial state is [1,2,3,4], i = 0, lstOut.Items.Count = 4

    after first iteration is becomes [2,3,4], i = 1, lstOut.Items.Count = 3

    so i points to item 3 !

    item 2 was skipped !

    a correct loop should be reversed (from last item in collection to first)

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

    or another way is to remove items at 0 position, while there items:

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

    Source: https://stackoverflow.com/questions/47944300/deleting-all-items-from-listview
    Author: ASh
    Creative Commons License
    This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Viewing 2 posts - 1 through 2 (of 2 total)

You must be logged in to reply to this topic.