Search code examples
c#wpfdata-binding

How to split a loaded filename into different columns in ListView?


I have a folder with txt files that have a specific naming scheme: name_number1_number2_number3.txt (e.g.: abcde_0045_0002_1001).

I load the files from my folder into my application and display them in a ListView. Now I'm trying to split the filename into four columns: name num1 num2 num3.

If I click on several rows during runtime, I need the full name to be able to process the files further. (I would also like to be able to sort by columns in the future). I've tried reading in the names and splitting them into multiple arrays using the .Split method and then displaying them, which didn't work. I also tried other controls (DataGrid) without success. What would be the best approach for my Problem? Would another WPF control be better than ListView?

My XAML:

Button DockPanel.Dock="Bottom" Content="Process"/>
    <ListView x:Name="TxtListView"  SelectionMode="Multiple" DockPanel.Dock="Top">
        <ListView.View>
            <GridView>
                <GridView.Columns>
                    <GridViewColumn>
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox Tag="{Binding .}" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListViewItem}}, Path=IsSelected}" />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn x:Name="NName" Header="Name"/>
                    <GridViewColumn x:Name="Num1" Header="Num 2"/>
                    <GridViewColumn x:Name="Num2" Header="Num 3"/>
                    <GridViewColumn x:Name="Num3" Header="Num 4"/>
                </GridView.Columns>
            </GridView>
        </ListView.View>
    </ListView>

Code Behind:

 InitializeComponent();

        //Read txt Files
        DirectoryInfo d = new DirectoryInfo(@"C:\txt");
        FileInfo[] txtFiles = d.GetFiles("*.txt");


        //Splitting txt string
        string[] name = new string[txtFiles.Length];
        string[] number1 = new string[txtFiles.Length];
        string[] number2 = new string[txtFiles.Length];
        string[] number3 = new string[txtFiles.Length];
      

        for (int i = 0; i < txtFiles.Length; i++)
        {
            string[] temp = txtFiles[i].ToString().Split('_', '.');
            name[i] = temp[0];
            number1[i] = temp[1];
            number2[i] = temp[2];
            number3[i] = temp[3];
        }

        TxtListView.ItemsSource = txtFiles;

My current ListView

I'm grateful for any advice!


Solution

  • Use DataGrid, you have to group the 4 segments (that you got after splitting the file path) in a "data transfer object" like this

    1. Create the FileDto
    public class FileDto
    {
        public string Name { set; get; }
        public string Num2 { set; get; }
        public string Num3 { set; get; }
        public string Num4 { set; get; }
    
        public FileDto(string s1, string s2, string s3, string s4)
        {
            Name = s1;
            Num2 = s2;
            Num3 = s3;
            Num4 = s4;
        }
    }
    
    1. Prepare the items for the DataGrid like this
    InitializeComponent();
    
    //Read txt Files
    DirectoryInfo d = new DirectoryInfo(@"C:\txt");
    FileInfo[] txtFiles = d.GetFiles("*.txt");
    
    List<FileDto> dataGridFiles = new List<FileDto>();
    
    for (int i = 0; i < txtFiles.Length; i++)
    {
        string[] temp = txtFiles[i].ToString().Split('_', '.');
        var fileDto = new FileDto(temp[0], temp[1], temp[2], temp[3]);
        dataGridFiles.Add(fileDto);
    }
    
    MyDataGrid.ItemsSource = dataGridFiles;
    
    1. DataGrid could be just like this
    <DataGrid
        AutoGenerateColumns="True"
        x:Name="MyDataGrid"/>
    
    1. When reading DataGrid rows, each row will represent a FileDto, so you can group the segments together to get the original file path.