ListView CheckBox data forwarding - deleting checked items

I am trying to remove all checked items in my list when I click the delete button. ListView

I saw what IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=IsSelected"

is mentioned in some places, but I don't know how I should combine it with the already bound IsChecked.

In my code, this is the exception: lvStores.Items.Remove(item);

I am importing CSV files with the following structure:
"ID", "NAME", CheckedINT
eg
"1662", "BØRSTER", 0 <- where 1 = checked, 0 = unchecked.
"1658", "BØRSTER", 1

I use this to iterate over the data in the ListView in a different method:

    // Loop through ListView
    foreach (var item in lvStores.Items.OfType<Store>())
    {
        // If 1 item in Listview is checked then
        if (item.IsChecked == true)
        {
            blnOk = true;
            return;
        }
    }

      

XAML

<Window x:Class="CloneMacro.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CloneMacro"
        mc:Ignorable="d"
        Title="Clone Macro" Height="348" Width="620.045" Closed="MainWindow_Closed" Icon="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\copy.png">
    <Grid Background="#FFDEDEDE" Margin="-1,0,-8,0" HorizontalAlignment="Left" Width="621">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Button x:Name="cmdNew" HorizontalAlignment="Left" Margin="39,36,0,0" VerticalAlignment="Top" Width="39" Height="40" ToolTip="New" Click="cmdNew_Click">
            <Image x:Name="imgNew" HorizontalAlignment="Left" Height="37" VerticalAlignment="Top" Width="36" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\Generic_Document.png" RenderTransformOrigin="0.172,1.089"/>
        </Button>
        <Button x:Name="cmdOpen" HorizontalAlignment="Left" Margin="80,36,0,0" VerticalAlignment="Top" Width="39" Height="40" ToolTip="Open" Click="cmdOpen_Click">
            <Image x:Name="imgOpen" HorizontalAlignment="Left" Height="37" VerticalAlignment="Top" Width="36" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\folder_Open_32xLG.png"/>
        </Button>
        <Button x:Name="cmdSave" HorizontalAlignment="Left" Margin="121,36,0,0" VerticalAlignment="Top" Width="39" Height="40" ToolTip="Save" Click="cmdSave_Click">
            <Image x:Name="imgSave" HorizontalAlignment="Left" Height="37" VerticalAlignment="Top" Width="36" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\save_16xLG.png"/>
        </Button>
        <Button x:Name="cmdDelete" HorizontalAlignment="Left" Margin="235,36,0,0" VerticalAlignment="Top" Width="39" Height="40" Click="cmdDelete_Click">
            <Image x:Name="imgDelete" HorizontalAlignment="Left" Height="33" VerticalAlignment="Top" Width="32" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\action_Cancel_16xLG.png" ToolTip="Delete" RenderTransformOrigin="1.334,0.534"/>
        </Button>
        <Button x:Name="cmdNewStore" HorizontalAlignment="Left" Margin="275,36,0,0" VerticalAlignment="Top" Width="39" Height="40" Click="cmdNewStore_Click">
            <Image x:Name="imgNewStore" HorizontalAlignment="Left" Height="37" VerticalAlignment="Top" Width="36" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\action_add_16xLG.png" ToolTip="Add New Store" RenderTransformOrigin="0.5,0.5"/>
        </Button>
        <Button x:Name="cmdExecute" HorizontalAlignment="Left" Margin="355,36,0,0" VerticalAlignment="Top" Width="39" Height="40" ToolTip="Execute" Click="cmdExecute_Click">
            <Image x:Name="image" HorizontalAlignment="Left" Height="37" VerticalAlignment="Top" Width="37" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\StatusAnnotations_Play_32xLG_color.png"/>
        </Button>
        <Button x:Name="cmdCancel" HorizontalAlignment="Left" Margin="395,36,0,0" VerticalAlignment="Top" Width="39" Height="40" ToolTip="Cancel" Click="cmdCancel_Click">
            <Image x:Name="imgCancel" HorizontalAlignment="Left" Height="37" VerticalAlignment="Top" Width="36" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\CancelApproval_32x32.png"/>
        </Button>
        <CheckBox x:Name="chOpenLastUsed" Content="Open Last Used File" Margin="456,48,0,0" VerticalAlignment="Top" Height="21" Width="147" HorizontalAlignment="Left"/>
        <ListView x:Name="lvStores" HorizontalAlignment="Left" Height="161" Margin="39,98,0,0" VerticalAlignment="Top" Width="466">
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Header="ID" Width="Auto">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <CheckBox Content="{Binding sID}" IsChecked="{Binding IsChecked}"/>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn Header="Name" Width="Auto" DisplayMemberBinding="{Binding Path=sName}"/>
                        <GridViewColumn Header="Import File" Width="Auto" DisplayMemberBinding="{Binding Path=sImportFile}"/>
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>
        <Label x:Name="lblProgress" x:FieldModifier="public" Content="Status Text" HorizontalAlignment="Left" Margin="40,264,0,0" VerticalAlignment="Top" Width="465" BorderThickness="1" BorderBrush="#FF7C7C7C"/>
        <Button x:Name="ComDialog" HorizontalAlignment="Left" Margin="533,152,0,0" VerticalAlignment="Top" Width="48" Height="51">
            <Image x:Name="imgComDialog" HorizontalAlignment="Left" Height="44" VerticalAlignment="Top" Width="48" Source="C:\Users\Niclas VMWare\Documents\Visual Studio 2015\Projects\CloneMacro\CloneMacro\images\DialogID_6220_32x.png"/>
        </Button>
    </Grid>
</Window>

      

CS

    public MainWindow()
    {
        // Leave this to show the UI
        InitializeComponent();

        lblProgress.Content = "";


        lvStores.ItemsSource = ReadCSV(@"C:\Users\Niclas VMWare\Downloads\TESTFILE.pcf");

    }

    // Fill ListView
    public class Store
    {
        public string sName { get; set; }
        public string sImportFile { get; set; }
        public string sID { get; set; }
        public bool IsChecked { get; set; }

        public Store(string id, string strName, string isChecked, string strImportFile)
        {
            sName = strName.Replace("\"","");
            sImportFile = Path.GetFileName(strImportFile);
            sID = id.Replace("\"","");

            // Convert isChecked to boolean
            // Do convertion outside the constructor to avoid any exception within
            int iBool = Convert.ToInt32(isChecked);

            switch (iBool)
            {
                case 0: IsChecked = false; break;
                case 1: IsChecked = true; break;
                default: throw new InvalidOperationException("Third value in PCF file must be 0 or 1!");
            }
        }
    }
    public IEnumerable<Store> ReadCSV(string fileName)
    {
        // Make sure the file extension is pcf
        string[] lines = File.ReadAllLines(Path.ChangeExtension(fileName, ".pcf").Replace("\"", ""), Encoding.GetEncoding(65001));

        // lines.Select allows to project each line as a Store
        // This will give an IEnumerable<Store> back.
        return lines.Select(line =>
        {
            string[] data = line.Split(',');
            // Return the store data
            // Return id, Name, isChecked (chkbox checked?), filename
            return new Store(data[0], data[1], data[2], fileName);
        });
    }
    // End Fill ListView

    private void cmdDelete_Click(object sender, RoutedEventArgs e)
    {
        // if selected
        foreach (var item in lvStores.Items.OfType<Store>())
        {
            if (item.IsChecked == true)
            {
                lvStores.Items.Remove(item);
            }
        }
    }

      

+3


source to share


1 answer


I would:

  • Use ObservableCollection
  • Implement INotifyPropertyChanged on your Store Class (or something similar ... others have suggested, by right, read the MVVM paradigm). These first two are required for the UI to update objects at runtime.
  • Iterate through the loop in reverse order, and remove each element one at a time as guaranteed.

MainWindow.xaml:

<Window x:Class="CloneMacro.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CloneMacro"
        mc:Ignorable="d"
        Title="Clone Macro" Height="348" Width="620.045">
    <Grid Background="#FFDEDEDE" Margin="-1,0,-8,0" HorizontalAlignment="Left" Width="621">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Button x:Name="cmdNew" HorizontalAlignment="Left" Margin="39,36,0,0" VerticalAlignment="Top" Width="39" Height="40" ToolTip="New" >
            New
        </Button>
        <Button x:Name="cmdOpen" HorizontalAlignment="Left" Margin="80,36,0,0" VerticalAlignment="Top" Width="39" Height="40" ToolTip="Open" Click="cmdOpen_Click">
            Open
        </Button>
        <Button x:Name="cmdSave" HorizontalAlignment="Left" Margin="121,36,0,0" VerticalAlignment="Top" Width="39" Height="40" ToolTip="Save">
            Save
        </Button>
        <Button x:Name="cmdDelete" HorizontalAlignment="Left" Margin="235,36,0,0" VerticalAlignment="Top" Width="39" Height="40" Click="cmdDelete_Click">
            Delete
        </Button>
        <Button x:Name="cmdNewStore" HorizontalAlignment="Left" Margin="275,36,0,0" VerticalAlignment="Top" Width="39" Height="40">
            New Store
        </Button>
        <Button x:Name="cmdExecute" HorizontalAlignment="Left" Margin="355,36,0,0" VerticalAlignment="Top" Width="39" Height="40" ToolTip="Execute">
            Execute
        </Button>
        <Button x:Name="cmdCancel" HorizontalAlignment="Left" Margin="395,36,0,0" VerticalAlignment="Top" Width="39" Height="40" ToolTip="Cancel">
            Cancel
        </Button>
        <CheckBox x:Name="chOpenLastUsed" Content="Open Last Used File" Margin="456,48,0,0" VerticalAlignment="Top" Height="21" Width="147" HorizontalAlignment="Left"/>
        <ListView x:Name="lvStores" HorizontalAlignment="Left" Height="161" Margin="39,98,0,0" VerticalAlignment="Top" Width="466">
            <ListView.View>
                <GridView>
                    <GridView.Columns>
                        <GridViewColumn Header="ID" Width="Auto">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <CheckBox Content="{Binding sID}" IsChecked="{Binding IsChecked}"/>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn Header="Name" Width="Auto" DisplayMemberBinding="{Binding Path=sName}"/>
                        <GridViewColumn Header="Import File" Width="Auto" DisplayMemberBinding="{Binding Path=sImportFile}"/>
                    </GridView.Columns>
                </GridView>
            </ListView.View>
        </ListView>
        <Label x:Name="lblProgress" x:FieldModifier="public" Content="Status Text" HorizontalAlignment="Left" Margin="40,264,0,0" VerticalAlignment="Top" Width="465" BorderThickness="1" BorderBrush="#FF7C7C7C"/>
        <Button x:Name="ComDialog" HorizontalAlignment="Left" Margin="533,152,0,0" VerticalAlignment="Top" Width="48" Height="51">
            Dialog
        </Button>
    </Grid>
</Window>

      



MainWindow.xaml.cs:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace CloneMacro
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        ObservableCollection<Store> stores;

        internal const string TESTFILE = @"C:\Temp\TESTFILE.pcf";
        public MainWindow()
        {
            // Leave this to show the UI
            InitializeComponent();

            lblProgress.Content = "";

            OpenFile( TESTFILE );
        }

        internal void OpenFile( string fileName )
        {
            stores = ReadCSV( TESTFILE );
            lvStores.ItemsSource = stores;
        }

        // Fill ListView
        public class Store : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            protected void OnPropertyChanged( string name )
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if ( handler != null )
                {
                    handler(this, new PropertyChangedEventArgs(name));
                }
            }

            public string sName { get; set; }
            public string sImportFile { get; set; }
            public string sID { get; set; }

            private bool isChecked;
            public bool IsChecked
            {
                get { return isChecked; }
                set
                {
                    if ( isChecked != value )
                    {
                        isChecked = value;
                        OnPropertyChanged("IsChecked");
                    }
                }
            }

            public Store( string id, string strName, string isChecked, string strImportFile )
            {
                sName = strName.Replace("\"", "");
                sImportFile = System.IO.Path.GetFileName(strImportFile);
                sID = id.Replace("\"", "");

                // Convert isChecked to boolean
                // Do convertion outside the constructor to avoid any exception within
                int iBool = Convert.ToInt32(isChecked);

                switch ( iBool )
                {
                    case 0: IsChecked = false; break;
                    case 1: IsChecked = true; break;
                    default: throw new InvalidOperationException("Third value in PCF file must be 0 or 1!");
                }
            }
        }

        public ObservableCollection<Store> ReadCSV( string fileName )
        {
            // Make sure the file extension is pcf
            string [] lines = File.ReadAllLines(
                System.IO.Path.ChangeExtension(fileName, ".pcf").Replace("\"", ""), Encoding.GetEncoding(65001));

            // lines.Select allows to project each line as a Store
            // This will give an IEnumerable<Store> back.
            var enumerable = lines.Select(line =>
            {
                string [] data = line.Split(',');
                // Return the store data
                // Return id, Name, isChecked (chkbox checked?), filename
                return new Store(data [0], data [1], data [2], fileName);
            });

            stores = new ObservableCollection<Store>();
            foreach ( var item in enumerable )
            {
                stores.Add( item );
            }
            return stores;
        }
        // End Fill ListView

        private void cmdDelete_Click( object sender, RoutedEventArgs e )
        {
            for ( int i = stores.Count - 1; i >= 0; i-- )
            {
                if ( stores[i].IsChecked )
                {
                    stores.RemoveAt( i );
                }
            }
        }

        private void cmdOpen_Click( object sender, RoutedEventArgs e )
        {
            OpenFile( TESTFILE );
        }

    }
}

      

TESTFILE.pcf:

"1662","BØRSTER",0
"1658","BØRSTER",1
"1669","A Møøse once bit my sister.",1

      

+2


source







All Articles