I want to put a search option in DataGridView, i.e., User types the string or int in TextBox and similar records the DataGridView should be highlighted. I tried it using KeyPress event but didn't work.
if (Char.IsLetter(e.KeyChar))
{
for (int i = 0; i < (dgemployee.Rows.Count); i++)
{
if (dgemployee.Rows[i].Cells["Employee"].Value.ToString().
StartsWith(e.KeyChar.ToString(), true,
CultureInfo.InvariantCulture))
{
dgemployee.Rows[i].Cells[0].Selected = true;
return;
}
}
Actually, I need to search the whole DataGridView, not only one column and row. So any best solution?
If your DataGridView is bound to a DataTable or a DataView, you can do this:
Create a BindingSource and make BindingSource.DataSource the Datatable or DataView that your DGV is currently using. Then set your DataGridView.DataSource to the BindingSource. Then you can use the BindingSource.Filter property to query your datasource by setting the BindingSource.Filterto your query string which will automatically filter the DGV. You can find the syntax here - it is very similar to basic SQL queries, except you can only use wild cards on the beginning and end of the string.
Use the DataView.RowFilter property.
Also take a look at DataTable.DefaultView
Take a look at this article I wrote some time back on filtering data real time.
private void txtsearchgroup_KeyUp(object sender, KeyEventArgs e) {
SqlConnection objconnection = new SqlConnection(servername and ...);
DataView Dv = new DataView();
objcommand = new SqlCommand("select name from groupitems", objconnection);
objdataadapter = new SqlDataAdapter();
objdataadapter.SelectCommand = new SqlCommand();
objdataadapter.SelectCommand = objcommand;
objdataset = new DataSet();
objconnection.Open();
objdataadapter.Fill(objdataset);
Dv.Table = objdataset.Tables[0];
Dv.RowFilter = " name LIKE '%" + txtsearchgroup.Text + "%'";
dataGridView1.DataSource = Dv;
objconnection.Close(); }
txtsearchgroup : name of textbox for search word in datagridview1 and
txtsearchgroup_KeyUp : event of keyup for search and filter word in datagridview1 and
select name from groupitems : name is field for groupitems table and
Dv.Table = objdataset.Tables[0] : zero (0) is first table in dataset
Related
How to program Combox in dataGridView?
The following code does not lead to the result.
Data tables parsitsya in Datatable.
I want to make the "combox" displayed for the "Type" field
Code
DataTable dt;
OleDbConnection connection;
OleDbDataAdapter adapter;
OleDbCommandBuilder commandBuilder;
static string catBD = #"z:\vs\csharp\prb\db_GridVAccess.accdb";
string connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}", catBD);
string sql = "SELECT * FROM tbl_01_Combox";
public Form5()
{
InitializeComponent();
using (OleDbConnection cn = new OleDbConnection())
{
connection = new OleDbConnection(connectionString);
connection.Open();
adapter = new OleDbDataAdapter(sql, connection);
commandBuilder = new OleDbCommandBuilder(adapter);
// На соновании DataTable
dt = new DataTable();
adapter.Fill(dt);
dataGridView1.DataSource = dt;
}
}
private void Form5_Load(object sender, EventArgs e)
{
// Ширина поля
dataGridView1.Columns[0].Width = 50;
// Комбокс
string[] countrys = new string[] { "США", "ОАЭ", "ЮАР" };
(dataGridView1.Columns[1] as DataGridViewComboBoxColumn).DataSource = countrys;
}
I believe the problem is your "countrys" isn't observable, plus it has to be a property.
Consider the following code:
private ObservableCollection<string> _Countries;
public ObservableCollection<string> Countries
{
get { return _Countries; }
set { _Countries = value; }
}
Initialize and set its contents in your Form5_Load and see if it works.
EDIT 1:
I was curious, so I actually created a project and tried to recreate the problem, and I believe the real problem here is that your DataGridView is populated according to the info you get from DB. I looked into it a bit further, and found this post on SO:
C# Replace default textbox in DataGridView with a Combobox
According to it, you can't change the type of the column to DataGridViewComboBoxColumn, after it's already been created as DataGridViewTextBoxColumn according to the data you got from DB. It also suggests two different approaches to the case, which do sound realistic. I hope you can figure it out, good luck.
EDIT 2:
Per your request, I'll try to figure the way to accomplish it with changing the data you get from DB.
In the following piece of code, you have a "dt" object which has data that you want to show in your DataGridView.
dt = new DataTable();
adapter.Fill(dt);
dataGridView1.DataSource = dt;
I've never done it myself, and I can't really recreate it anyhow fast, but I suggest you try and play with the contents of the object "dt". I suppose the code which happens in "adapter.Fill" creates the DataTable according to the data from db, you can try and add there some code which will add a List instead of a string for the "type" column (It will then help create a ComboBoxColumn instead of TextBoxColumn as far as I follow). I actually checked it our right now, and it looks to be a bit complicated, but I really don't know what's happening there in your program, it might just be as easy as it gets.
Anyway, I did try to do it another way, instead of changing the existing column type, I added a new DataGridViewComboBoxColumn of my own, to the end of the automatically populated DataGridView:
DataTable dt = new DataTable();
dataGridView2.DataSource = dt;
DataGridViewComboBoxColumn newColumn = new DataGridViewComboBoxColumn();
newColumn.DataSource = new List<string> { "asd", "qwe", "zxc" };
dataGridView2.Columns.Add(newColumn);
You then can just remove/delete the irrelevant "type" column that you got from db. But, then you'll face some other problems along the way, as connecting the selected object in combobox to the other data in the row. It's not complicated, but can get relatively ugly.
Edited:
If you have set the DataGridView.AutoGenerateColumns = true and the columns are generated automatically, the type of column "type" is not ComboBox. in that case you can create a new column, set it up and then replace the old column with it:
DataGridViewComboBoxColumn column = new DataGridViewComboBoxColumn();
int i = 0;
column.DataPropertyName = "type";
column.DataSource = countrys.Select(x => new { Key = i++, Value = x }).ToList();
column.DisplayMember = "Value";
column.ValueMember = "Key";
dataGridView1.Columns.RemoveAt(1);
dataGridView1.Columns.Insert(1, column);
the previous code didn't work because column[1] could not be cast into DataGridViewComboBoxColumn so (dataGridView1.Columns[1] as DataGridViewComboBoxColumn) would return a null and because you have put the code in Form_Load the Exception was omitted.
Original:
try this:
int i = 0;
(dataGridView1.Columns[1] as DataGridViewComboBoxColumn).DataSource = countrys.Select(x=> new {Key = i++, Value = x}).ToList();
(dataGridView1.Columns[1] as DataGridViewComboBoxColumn).DisplayMember = "Value";
(dataGridView1.Columns[1] as DataGridViewComboBoxColumn).ValueMember = "Key";
I have searched for this but could not find any solution for textchanged event outside the gridview causing changes in results. I am unable to attach image being a newbie. I want results shown in gridview through data table to update according to what I type in textbox placed outside of gridview. code in c# will be appreciated. In the end, I want to retrieve ID on pressing ENTER key to use further.
private void textBox1_TextChanged(object sender, EventArgs e)
{
DataTable table = new DataTable();
string sql; table.Columns.Add("Name");
dbconnect db = new dbconnect();
db.createconnection();
sql = "select custcompany from customer";
db.dbadapter = new OleDbDataAdapter(sql, db.dbconnection);
DataTable dtt = new DataTable();
db.dbadapter.Fill(dtt);
for (int i = 0; i < dtt.Rows.Count; i++)
{
table.Rows.Add(dtt.Rows[i][0]);
}
sql = "select suppcompany from supplier";
db.dbadapter = new OleDbDataAdapter(sql, db.dbconnection);
DataTable dtt1 = new DataTable();
db.dbadapter.Fill(dtt1);
for (int i = 0; i < dtt1.Rows.Count; i++)
{
table.Rows.Add(dtt1.Rows[i][0]);
}
dataGridView1.DataSource = table;
if (textBox1.Text != "")
{
DataView dv = new DataView();
dv.RowFilter = string.Format("Name = '{0}'", textBox1.Text);
dataGridView1.DataSource = dv;
}
else if (textBox1.Text == "")
{
dataGridView1.DataSource = table;
}
}
table is the name of DataTable populated on Load event.
If test box has value, you are creating a new instance of DataView and assigning it to the dataGridView1, my question is is there value in DataView object? If you are doing exactly what you have given in the question then it won't work, because dv doesn't have value to show in the dataGridView1.
Get the table data on TextChanged event by accessing the database. If you have any code where you are getting the database values into the table then use it in this event before binding to the DataGridView1.
Because the table value will be lost after PostBack. So you need to reload the value into table again. Try the following,
private void textBox1_TextChanged(object sender, EventArgs e)
{
//table = fill the table with proper values by accessing the database
if (textBox1.Text != "")
{
DataView dv = table.DefaultView;
dv.RowFilter = string.Format("Name = '{0}'", textBox1.Text);
dataGridView1.DataSource = dv;
dataGridView1.DataBind();
}
else if (textBox1.Text == "")
{
dataGridView1.DataSource = table;
dataGridView1.DataBind();
}
}
Update
To search names that begins with letters use,
dv.RowFilter = string.Format("Name like '{0}%'", textBox1.Text);
To search names that contains a letters use,
dv.RowFilter = string.Format("Name like '%{0}%'", textBox1.Text);
To search names that ends with letters,
dv.RowFilter = string.Format("Name like '%{0}'", textBox1.Text);
I have a form in which a simple gridview is populated by a table in database having columns like TicketID, Name, Company, Product etc. Now I want to add a search feature so that user could search by customer name or company or TicketID.
How can I do that ? I want to place a combox box, textbox and a simple "search" button above datagrid. When the user selects TicketID for example, enters "1" in textbox and presses "Search", it should refresh datagrid with entry where TicketID = 1.
Now I don't have any idea on how to implement it. Googled for it but found nothing useful. So any help in this regard will be appreciated.
Regards.
You may look into:
BindingSource bs = new BindingSource();
bs.DataSource = dataGridView1.DataSource;
bs.Filter = columnNameToSearch + " like '%" + textBox1.Text + "%'";
dataGridView1.DataSource = bs;
This will show you records containing text from textbox1 in column of your choice. I did exactly what you are asking for:)
Create a Textbox for search input and use the following code on its TextChanged event
private void txtSearch_TextChanged(object sender, EventArgs e)
{
(dataGridView.DataSource as DataTable).DefaultView.RowFilter = string.Format("TicketID like '{0}%' OR Product like '{0}%' OR Name like '{0}%' OR Product like '{0}%'", txtSearch.Text);
}
If you want refresh your DataSource depended on the search parameters, then you need to build a new SQL query depended on then "search" controls:
Will be better of you show your code of getting data from database,
but this is my shot with manual SQL-query creating:
//...
StringBuilder query = new StringBuilder();
query.AppendLine("SELECT TicketID, Name, Company, Product");
query.AppendLine("FROM YourTable WHERE 1=1");
if (txtSearch.TextLength > 0)
{
query.AppendLine("AND TicketID = #TicketID");
//Here add sqlparameter with textbox value
}
//... and so on
BindingSource bs = new BindingSource();
bs.DataSource = dataGridView1.DataSource;
bs.Filter = "[database column Name To Search] like '%" + textBox1.Text + "%'";
dataGridView1.DataSource = bs;
BindingSource bs = new BindingSource();
bs.DataSource = dgrid.DataSource;
bs.Filter = "Full_Name like '%" + tsptxt_search.Text + "%'";
dgrid.DataSource = bs;
This works for me.
What you need, filtering, not searching... Searching is highlighting the correct row from the set
Set grid DataSource to the result of DataTable.Select method
dtData.Select("TicketID = 1")
Also take a look to this post
DataSet ds;
DataView dv;
public Form1()
{
InitializeComponent();
ds = new DataSet();
dv = new DataView();
}
private void Form1_Load(object sender, EventArgs e)
{
ds=SelectStudents();
dv.Table = ds.Tables[0];
dataGridView1.DataSource = dv;
}
Now in the text_changed event of the textbox, write below code
dv.RowFilter = "StudentName like '%" + textBox1.Text + "%'";
dataGridView1.DataSource = dv;
I have 2 tables, product_items and category.
And 2 combobox. I want filter another combobox, after selected category.
Sorry for my bad english speak :), i tryed this 9h, and no solution get :/
My code how much i have writed.
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter("select itemid, itemname, pcatid from produkti_items_tab", TestConnection);
da.Fill(ds, "FillDropDown");
comboBox1.DataSource = ds.Tables["FillDropDown"].DefaultView;
comboBox1.DisplayMember = "itemname";
comboBox1.ValueMember = "itemid";
//============================================
DataSet ddd = new DataSet();
SqlDataAdapter dada = new SqlDataAdapter("select pcatid, pcatname from produkti_cat_tab", TestConnection);
dada.Fill(ddd, "FillDropDownzzz");
comboBox2.DataSource = ddd.Tables["FillDropDownzzz"].DefaultView;
comboBox2.DisplayMember = "pcatname";
comboBox2.ValueMember = "pcatid";
But i dont know what i should write here:
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
//how filter :/
}
Not sure, need to test this, but, the DataView binded to the first combobox has a RowFilter property.
Setting this property to the appropriate condition should remove the items that doesn't belong to the current category selected
if(comboBox2.SelectedValue != null)
{
DataView dv = comboBox1.DataSource as DataView;
dv.RowFilter = "pcatid = " + comboBox2.SelectedValue.ToString();
}
Hello I have a datagridview that already has many, many rows added to it. I also have a textbox that I want to filter the rows out of the datagridview rows if they do not match. I somehow want to connect the textbox to a column to show AND hide the rows. The table was populated using:
public void readExcelFile()
{
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source = " + Properties.Settings.Default.excelFilePath + "; Extended Properties = \"Excel 8.0;HDR=Yes;IMEX=1\";";
string query = String.Format("select * from [{0}$]", "Batch Export");
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(query, connectionString);
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet);
resultsGrid.DataSource = dataSet.Tables[0];
}
Now when I start typing "John" into the textbox and the first column is "Name", I want all the rows whose Name cell doesn't start with "J", then "Jo", etc. when I delete characters, I want the rows to come back. Is this possible? I've done this before using SQL queries to a DB, but this source is different. And I had to clear the table on every textChanged event. There are about 20k rows here.
Before you assign the Table to the resultGrid.DataSource, you can use DataTable.Select:
var strExpr = "CustomerFirstName = 'John' AND OrderCount > 2";
var strSort = "OrderCount DESC";
// Use the Select method to find all rows matching the filter.
foundRows = ds.Table[0].Select(strExpr, strSort);
Or you can use DataView:
ds.Tables[0].DefaultView.RowFilter = strExpr;
We can used a binding source to filter the data.
private BindingSource dashBoardBindingSource = new BindingSource();
dashBoardBindingSource.DataSource= dataSet.Tables[0];
resultsGrid.DataSource=dashBoardBindingSource;
string filterCriteria = "CustomerFirstName={0}";
dashBoardBindingSource.Filter=string.Format(CultureInfo.CurrentCulture, filterCriteria, textboxName.text);