ListView CheckBox数据绑定 - 删除选中的项目

时间:2017-08-02 13:11:17

标签: c# wpf listview checkbox data-binding

当我点击删除按钮时,我试图删除列表视图中的所有选中项目。 ListView

我看到IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=IsSelected"被提到很多地方,但我不知道应该如何将它与我已经存在的IsChecked绑定结合起来。

在我的代码中,这是抛出异常: lvStores.Items.Remove(item);

我正在导入具有以下结构的CSV文件:
“ID”, “NAME”,CheckedINT
例如
“1662”,“BØRSTER”,0 < - 其中1 =已选中,0 =未选中。
“1658”, “BØRSTER”,1

我使用它以另一种方法遍历ListView中的数据:

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

1 个答案:

答案 0 :(得分:2)

我会:

  1. 使用ObservableCollection
  2. 在您的网站上实施INotifyPropertyChanged 存储类(或类似的东西......其他人已经建议,正确地阅读MVVM范例)。前两个是必要的,以确保您的 UI正在运行时更新对象。
  3. 在循环中迭代 反向订单,并按照保证一次删除每个项目。
  4. 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