1
votes

I'm trying to write a program which will made a datagridview based on a text file. See code below.

private void Button1_Click(object sender, EventArgs e)
{
    ls_datenTabelle.Clear();
    ls_datenTabelle.Columns.Clear();

    string kdstr = (comboBox1.SelectedItem.ToString());
    string fileName = "ls.txt";
    string fileName2 = kdstr + ".txt";
    string sourcePath = @"H:\import_directoy\customer\" + kdstr;
    string tempPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
    string dmitempPath = @"program_name\";
    string targetPath = Path.Combine(tempPath, dmitempPath);

    File.Delete(targetPath + "output");

    string sourceFileName = Path.Combine(sourcePath, fileName);
    string destFile = Path.Combine(targetPath, fileName2);

    Directory.CreateDirectory(targetPath);

    File.Copy(sourceFileName, destFile, overwrite: true);

    using (var output = File.Create(targetPath + "output"))
    {
        foreach (var file in new[] { "H:\\directoy1\\directoy2\\index.config", destFile })
        {
            using (var input = File.OpenRead(file))
            {
                input.CopyTo(output);
            }
        }
    }

    string[] raw_text = File.ReadAllLines(targetPath + "output", Encoding.Default);
    string[] data_col = null;
    int x = 0;
    foreach (string text_line in raw_text)
    {
        data_col = text_line.Split(';');

        if (x == 0)
        {
            for (int i = 0; i <= data_col.Count() - 1; i++)
            {
                ls_datenTabelle.Columns.Add(data_col[i]);
            }
            x++;
        }
        else
        {
            ls_datenTabelle.Rows.Add(data_col);
        }
    }

    ls_dataGridView.DataSource = ls_datenTabelle;
    this.Controls.Add(ls_dataGridView);
    ls_dataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
    ls_dataGridView.AllowUserToAddRows = false;
}

Now I want to search all over this datatable/datagridview and I will show the rows if the search function found the searchvalue in any column.

But I dodn't know how. The header of the table could change every day. So this code doesn't work for me:

public void findingValue(object sender, EventArgs e)
{
    string searchValue = textBox1.Text;

    DataView data = ls_datenTabelle.DefaultView;

    ls_dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
    data.RowFilter = string.Format("Name like '" + searchValue + "%'");
}

The program will find only rows where the searchValue is in the "Name" column and not one of the other 18 (umknown) columns.

1
Loop over the columns and build a more complex filter! - TaW

1 Answers

0
votes

Here is an example which uses Linq to loop over the columns in the DataTable:

if (searchValue == "")  data.RowFilter = "";
else
{
    var cols = ls_datenTabelle.Columns.Cast<DataColumn>().Select(x => x.ColumnName);
    var filter = cols.Select(x => x + " like '" + searchValue + "%'")
                     .Aggregate((a, b) => a + " OR " + b);
    data.RowFilter = filter;
}

First we collect the column names and then we build a filter from them, each part connectd with a OR clause.

You could also use Join or good old loops..

Note that this assumes that all columns allow searching for strings, i.e. no numbers etc..

If this is not true you will want to either pick only the string columns or change the filter for non-string columns, if searching them makes any sense.

To restrict the search to string columns simply insert

.Where(x => x.DataType == typeof(string))

between Cast and Select, so that cols contains only searchable columns..

If instead you want to search numeric columns you could write the filter like this:

var filter = cols.Select(x => "Convert(" + x + ", 'System.String')  like '" 
                            + searchValue + "%'").Aggregate((a, b) => a + " OR " + b);

This uses the Convert function of the expression syntax . But why would one search for numbers starting with some digits..?

Here is a test with 2 string, 1 numeric and one datetime columns. The filter works for all; note that for the test I have added an extra '%' to extend the search to the whole values, not just the start..

enter image description here