Search code examples
wpf.net-core

I am searching folders and subfolders for documents length that exceeds a value and put the results in a list


This is a WPF app with a button to browse and select a folder. The folder selection returns a path to traverse sub folders and files and evaluate the path length. The results are correct but it breaks binding the results to a list item in the view.

namespace FileLengthWPF
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            lvFiles.Items.Add(LengthExceeded);
        }

        private List _lengthExceeded;
        public List LengthExceeded
        {
            get => _lengthExceeded;
            set => _lengthExceeded = value;
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var openFileDlg = new FolderBrowserDialog();
            openFileDlg.InitialDirectory = "C:\\TempSearchFolder";
            var showDialog = openFileDlg.ShowDialog();

            if (showDialog == System.Windows.Forms.DialogResult.OK)
            {
                var directoryPath = openFileDlg.SelectedPath;

                EvaluateFolders(directoryPath);
            }
        }

        private static List<string> EvaluateFolders(string folderPath)
        {
            const int filePathMax = 240;
            var files = Directory.GetFiles(folderPath, "*.*", SearchOption.AllDirectories);

            var lengthExceeded = new List<string>();
            foreach (var file in files)
            {
                if (file.Length <= filePathMax) continue;
                lengthExceeded.Add(file);
            }
            return lengthExceeded;
        }
    }
}

From EvaluateFolders return LengthExceeded is populated correctly but the datacontext does not get assigned.

The list view is by name

<ListView Name="lvFiles" Grid.Row="1" Margin="0, 50, 0, 0"/>

how do I get the results to the view? Thanks for any help!


Solution

  • set the DataContext, use an ObservableCollection and dont forget to bind the collection with ItemSource like this:

    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Windows;
    
    namespace WpfApp1
    {
        public partial class MainWindow : Window
        {
            public ObservableCollection<string> LengthExceeded { get; set; }
            public MainWindow()
            {
                InitializeComponent();
                DataContext = this;
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                var list = new List<string>();
                list.Add("Folder1/file1");
                list.Add("Folder1/file2");
                list.Add("Folder1/file3");
                LengthExceeded = new ObservableCollection<string>(list);
                lvFiles.ItemsSource = LengthExceeded;
            }
        }
    }
    

    Another way is to bind directly in the xaml file;

    just rewrite your cs file:

    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Windows;
    
    namespace WpfApp1
    {
        public partial class MainWindow : Window, INotifyPropertyChanged
        {
            private ObservableCollection<string> lengthExceeded ;
            public ObservableCollection<string> LengthExceeded
            {
                get { return lengthExceeded; }
                set
                {
                    lengthExceeded = value;
                    OnPropertyChanged();
                }
            }
            public MainWindow()
            {
                InitializeComponent();
                DataContext = this;
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                var list = new List<string>();
                list.Add("Folder1/file1");
                list.Add("Folder1/file2");
                list.Add("Folder1/file3");
                LengthExceeded = new ObservableCollection<string>(list);
                //lvFiles.ItemsSource = LengthExceeded;
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected void OnPropertyChanged([CallerMemberName] string name = null)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
            }
        }
    }
    

    and define ItemsSource in your xaml instead to bind in your code:

    <ListView Name="lvFiles" Grid.Row="1" Margin="0, 50, 0, 50"
              ItemsSource="{Binding LengthExceeded}"/>