簡體   English   中英

使用文本框過濾 DataGridView

[英]Filter DataGridView with TextBox

我有一個DataGridView和一個TextBox 我需要使用TextBox過濾DataGridViewSQL中 DB 中的值。

像這樣的東西:

在此處輸入圖片說明

這是我的代碼:

public partial class Form1 : Form
    {
        private DataSet dataSet;
        private SqlDataAdapter adapter;
        private BindingSource bindingSource = new BindingSource();
        private DataView dataView = new DataView();

    public Form1()
    {
        InitializeComponent();
    }

    private void GetData(string valor)
    {
        try
        {
            // Initialize the DataSet.
            dataSet = new DataSet();
            dataSet.Tables.Add(new DataTable());
            dataSet.Tables[0].Columns.Add("numberAsString", typeof(string));
            dataSet.Locale = CultureInfo.InvariantCulture;

            // Create the connection string for the AdventureWorks sample database.
            string connectionString = "connection ";

            // Create the command strings for querying the Contact table.
            string contactSelectCommand = "SELECT Titulo as Título FROM V_CuetaWeb WHERE Titulo LIKE ('" + valor + "%') GROUP BY titulo ORDER BY titulo DESC";

            // Create the contacts data adapter.
            adapter = new SqlDataAdapter(
                contactSelectCommand,
                connectionString);

            // Create a command builder to generate SQL update, insert, and
            // delete commands based on the contacts select command. These are used to
            // update the database.
            SqlCommandBuilder contactsCommandBuilder = new SqlCommandBuilder(adapter);

            // Fill the data set with the contact information.
            adapter.Fill(dataSet, "V_CuetaWeb");
        }
        catch (SqlException ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {

        DataGridViewCheckBoxColumn chk = new DataGridViewCheckBoxColumn();
        chk.HeaderText = "Seleccione";
        chk.Name = "check";
        dtgTitulo.Columns.Add(chk);
        dtgTitulo.AllowUserToAddRows = false;

        dataSet = new DataSet();

        GetData(txtFiltroTitulo.Text);

        dtgTitulo.DataSource = bindingSource;

        // Create a LinqDataView from a LINQ to DataSet query and bind it 
        // to the Windows forms control.
        EnumerableRowCollection<DataRow> contactQuery = from row in dataSet.Tables["V_CuetaWeb"].AsEnumerable()
                                                        orderby row.Field<double>("Título") descending
                                                        select row;

        dataView = contactQuery.AsDataView();

        // Bind the DataGridView to the BindingSource.
        bindingSource.DataSource = dataView;

        string value = "";
        dtgTitulo.DataSource = bindingSource;
        bindingSource.Filter = "Título LIKE('" + Convert.ToInt64(value) + "%')";
        dtgTitulo.AutoResizeColumns();
    }

    private void txtFiltroTitulo_TextChanged(object sender, EventArgs e)
    {
        GetData(txtFiltroTitulo.Text);
    }
}

但不起作用,因為“título”是 SQL 中的浮點數據。 那么,有什么依據嗎?

將 Titulo 轉換為 varchar,就像這樣......

SELECT … WHERE CAST(Titulo AS varchar(50)) LIKE ('" + valor + "%') … 

而過濾器可能是這樣的......

bindingSource.Filter = "CONVERT(Título, 'System.String') LIKE('" + Convert.ToInt64(value) + "%')";

你描述的問題是雙重的。 首先,代碼是將復選框列“添加”到DataGridView本身! 這是一個問題,因為網格的DataSource不“知道”這個“添加”的列。 因此,當您對數據源應用“過濾器”時,該過濾器不會知道復選框列,並且顯然不會維護/關心“哪些”復選框已被選中或未選中。 要維護過濾器中的復選框,復選框列需要位於數據源本身中。

其次,當用戶更改過濾器文本框中的文本時,代碼似乎在重新查詢數據庫。 這很奇怪,我敢打賭你可能想重新考慮一下。 示例:每次用戶在文本框中鍵入一個字符時,代碼都會重新查詢數據庫。 如果用戶想“輸入”123,那么……當用戶輸入“1”時,數據庫被查詢,當用戶輸入“2”時再次查詢,當用戶輸入“3”時再次查詢。 這顯然是不必要的,可以歸類為破壞數據庫。

不要誤會我的意思,從某種意義上說,當用戶鍵入“1”,然后是“2”,最后是“3”時,我們確實想要“過濾”數據……您只是不想重新查詢數據庫來做到這一點。 為了避免這種數據庫破壞,代碼可以創建一個保存原始數據的“全局”變量,然后,當我們要過濾數據時,您可以從原始數據中獲取過濾后的副本,而不是重新查詢數據庫. 這意味着代碼只會查詢數據庫一次。

鑒於此,下面的代碼演示了將復選框列添加到網格DataSource DataTable ......而不是添加到網格本身。 這將在過濾時保留復選框。 此外,該代碼不會在鍵入每個過濾字符時重新查詢數據庫,而是過濾原始數據源。 這是通過從原始數據創建一個新的DataView然后針對輸入的每個字符過濾該DataView來實現的。

希望這有幫助並且有意義。

表單的加載方法可能看起來像……

DataSet ds;

public Form1() {
  InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e) {
  ds = new DataSet();
  ds.Tables.Add(GetDataFromDB());
  ds.Tables[0].Columns.Add("Select", typeof(bool));
  dataGridView1.DataSource = ds.Tables[0];
}

GetDataFromDB返回一個DataTable ,其中有一 (1) 個名為“Title”的列,其類型為double 然后我們將一列添加到從數據庫返回的DataTable 此列名為“Select”,類型為bool ... 復選框列。 現在,篩選時將保留復選框。

最后,當用戶在過濾器文本框中輸入文本時“過濾”數據......

private void textBox1_TextChanged(object sender, EventArgs e) {
  DataView dv = new DataView(ds.Tables[0]);
  if (double.TryParse(textBox1.Text, out double value)) {
    dv.RowFilter = "CONVERT(Title, 'System.String') LIKE('" + value + "%')";
  }
  dataGridView1.DataSource = dv;
}

在這里,我們從原始數據創建一個“新” DataView ,然后使用文本框中的文本過濾該DataView ,然后將網格設置為這個新DataView 請注意, double.TryParse方法用於過濾掉用戶鍵入的任何不是數字或為空的文本,在這種情況下,過濾器將顯示所有數據。

為了完成這個例子,下面是一種獲取一些測試數據進行測試的方法。

private DataTable GetDataFromDB() {
  DataTable dt = new DataTable();
  dt.TableName = "Titles";
  Random rand = new Random();
  dt.Columns.Add("Title", typeof(double));
  for (int i = 0; i < 3000; i++) {
    dt.Rows.Add(rand.Next(0, 1000));
  }
  return dt;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM