C# 将数据加载到Listview(WPF)

C# 将数据加载到Listview(WPF),c#,wpf,listview,itemssource,C#,Wpf,Listview,Itemssource,我正在尝试制作一个重复的文件检测器(相关问题:)。我的总体结构如下: 扫描目录并将每个文件所需的详细信息加载到DupInfo对象中 计算与其他文件大小匹配的任何文件的CRC 显示任何具有匹配大小和CRC(以及可选的基本目录)的文件,并允许用户检查要删除的文件(手动和使用“检查所有第一个副本”之类的按钮) 删除所选文件 我在第三步遇到了问题。步骤1和2中的数据位于DupInfo对象列表中。下面是类定义 public class DupInfo { public string

我正在尝试制作一个重复的文件检测器(相关问题:)。我的总体结构如下:

  • 扫描目录并将每个文件所需的详细信息加载到DupInfo对象中
  • 计算与其他文件大小匹配的任何文件的CRC
  • 显示任何具有匹配大小和CRC(以及可选的基本目录)的文件,并允许用户检查要删除的文件(手动和使用“检查所有第一个副本”之类的按钮)
  • 删除所选文件
  • 我在第三步遇到了问题。步骤1和2中的数据位于DupInfo对象列表中。下面是类定义

    public class DupInfo
        {
            public string FullName { get; set; }
            public long Size { get; set; }
            public uint? CheckSum { get; set; }
            public string BaseDirectory { get; set; }
            public DupInfo(FileInfo file, Crc32 crc, int level)
            {
                FullName = file.FullName;
                Size = file.Length;
                CheckSum = crc.ComputeChecksum(File.ReadAllBytes(FullName));
                BaseDirectory = FullName.Substring(0,FullName.NthIndexOf("\\",level));
            }
            public DupInfo(FileInfo file, int level)
            {
                FullName = file.FullName;
                Size = file.Length;
                BaseDirectory = FullName.Substring(0, FullName.NthIndexOf("\\", level));
            }
    
        }
    
    我的问题是:

  • 从自定义类(DupInfo)列表将数据加载到Listview对象的最佳方式是什么

  • 如果Listview不是显示重复集的最佳工具,那么什么是最佳工具


  • 我将使用绑定到
    可观察集合的数据网格

    结果:

    更新1:

    我们没有可用的AddRange,但为此定义了扩展方法:

    public static class ExtensionMethods
    {
        public static void AddRange(this ObservableCollection<DupInfo> value, List<DupInfo> list)
        {
            foreach (var dup in list)
                value.Add(dup);
        }
    }
    

    就这样。祝你好运

    谢谢你,我喜欢这个主意。我想知道如何将DupInfo列表转换为“items”对象。是否有addrange或copyto方法可用于ObservableCollection?或者我可以将ItemsSource设置为某个值。我应该将项设置为一个LINQ查询来转换数据吗?事实上,在进一步查看代码之后,我想我误解了。它看起来不需要任何转换,但将直接显示来自DupInfo对象的DupInfo字段。对吗?如果是,如何添加整个dupInfos列表?我可以使用AddRange()来执行此操作吗?@KalevMaricq DataGrid有一个默认为true的属性名AutoGenerateColumns。如果保持这样,就不需要其他转换。但是,如果要为列定义模板,请将其设置为false,然后在此处查看如何定义DataGridTemplateColumn。@KalevMaricq是的,AddRange扩展应该可以为您完成此工作。谢谢。我试着走这条路。如何添加复选框,以便用户可以指示要删除的文件?
    public partial class MainWindow : Window
    {
        public ObservableCollection<DupInfo> items { get; set; }
    
        public MainWindow()
        {
            InitializeComponent();
            items = new ObservableCollection<DupInfo>();
    
            items.Add(new DupInfo() { BaseDirectory = "Directory1", CheckSum = 0xFF, FullName = "Info1", Size = 100 });
            items.Add(new DupInfo() { BaseDirectory = "Directory2", CheckSum = 0xFE, FullName = "Info2", Size = 150 });
            items.Add(new DupInfo() { BaseDirectory = "Directory2", CheckSum = 0xFD, FullName = "Info3", Size = 200 });
            this.DataContext = this;
    
        }
    }
    
    public class DupInfo
    {
        public string FullName { get; set; }
        public long Size { get; set; }
        public uint? CheckSum { get; set; }
        public string BaseDirectory { get; set; }
    }
    
    public static class ExtensionMethods
    {
        public static void AddRange(this ObservableCollection<DupInfo> value, List<DupInfo> list)
        {
            foreach (var dup in list)
                value.Add(dup);
        }
    }
    
    public partial class MainWindow : Window
    {
        public ObservableCollection<DupInfo> items { get; set; }
    
        List<DupInfo> initialList { get; set; }
    
        public MainWindow()
        {
            InitializeComponent();
            items = new ObservableCollection<DupInfo>();
            initialList = new List<DupInfo>();
    
            initialList.Add(new DupInfo() { BaseDirectory = "Directory1", CheckSum = 0xFF, FullName = "Info1", Size = 100 });
            initialList.Add(new DupInfo() { BaseDirectory = "Directory2", CheckSum = 0xFE, FullName = "Info2", Size = 150 });
            initialList.Add(new DupInfo() { BaseDirectory = "Directory2", CheckSum = 0xFD, FullName = "Info3", Size = 200 });
    
            items.AddRange(initialList);
    
            this.DataContext = this;
    
        }
    }
    
    public static class ExtensionMethods
    {
        public static void AddRange(this ObservableCollection<DupInfo> value, List<DupInfo> list)
        {
            foreach (var dup in list)
                value.Add(dup);
        }
    }
    
        public  ObservableCollection<DupInfo> items
        {
            get { return ( ObservableCollection<DupInfo>)GetValue(itemsProperty); }
            set { SetValue(itemsProperty, value); }
        }
    
        // Using a DependencyProperty as the backing store for items.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty itemsProperty =
            DependencyProperty.Register("items", typeof( ObservableCollection<DupInfo>), typeof(MainWindow), new PropertyMetadata(null));
    
    <Window x:Class="DataGridDupInfoStack.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel>
            <DataGrid ItemsSource="{Binding items}" AutoGenerateColumns="False" CanUserAddRows="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Full Name" Binding="{Binding FullName}" />
                    <DataGridTextColumn Header="Size" Binding="{Binding Size}" />
                    <DataGridTextColumn Header="CheckSum" Binding="{Binding CheckSum}" />
                    <DataGridTextColumn Header="BaseDirectory" Binding="{Binding BaseDirectory}" />
                    <DataGridTemplateColumn Header="Mark for deletion">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="{Binding Path=ToDelete, UpdateSourceTrigger=PropertyChanged}" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
            <Button Content="Delete" Click="btnDelete_Click"/>
        </StackPanel>
    </Grid>
    </Window>
    
    public partial class MainWindow : Window
    {
    
    
        public ObservableCollection<DupInfo> items
        {
            get { return (ObservableCollection<DupInfo>)GetValue(itemsProperty); }
            set { SetValue(itemsProperty, value); }
        }
    
        // Using a DependencyProperty as the backing store for items.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty itemsProperty =
            DependencyProperty.Register("items", typeof(ObservableCollection<DupInfo>), typeof(MainWindow), new PropertyMetadata(null));
    
    
    
        List<DupInfo> initialList { get; set; }
    
        public MainWindow()
        {
            InitializeComponent();
            items = new ObservableCollection<DupInfo>();
            initialList = new List<DupInfo>();
    
            initialList.Add(new DupInfo() { BaseDirectory = "Directory1", CheckSum = 0xFF, FullName = "Info1", Size = 100 });
            initialList.Add(new DupInfo() { BaseDirectory = "Directory2", CheckSum = 0xFE, FullName = "Info2", Size = 150 });
            initialList.Add(new DupInfo() { BaseDirectory = "Directory2", CheckSum = 0xFD, FullName = "Info3", Size = 200 });
    
            items.AddRange(initialList);
    
            this.DataContext = this;
        }
    
    
        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            foreach (var dup in items.ToList())
            {
                if (dup.ToDelete)
                {
                    items.Remove(dup);
                }
            }
        }
    }
    
    public static class ExtensionMethods
    {
        public static void AddRange(this ObservableCollection<DupInfo> value, List<DupInfo> list)
        {
            foreach (var dup in list)
                value.Add(dup);
        }
    }
    
    public class DupInfo : INotifyPropertyChanged
    {
        private bool _ToDelete;
    
        public bool ToDelete
        {
            get { return _ToDelete; }
            set
            {
                _ToDelete = value;
                PropertyChanged(this, new PropertyChangedEventArgs("ToDelete"));
            }
        }
    
        public string FullName { get; set; }
        public long Size { get; set; }
        public uint? CheckSum { get; set; }
        public string BaseDirectory { get; set; }
    
        public event PropertyChangedEventHandler PropertyChanged = delegate { };
    }