Implement Search from database as alphabets are entered - c#

I have written a code that searches specific string from database table.what i want to implement is search like when we search friends on facebook means it returns results matching to the input given even if it is partial
for example if i want to search ANDREW as soon as i enter single character results should start to appear if i enter "an" like
andy
andrew
and....
here is my code for textbox text changed method
table = new DataTable();
table.Columns.Add("Name");
table.Columns.Add("Type");
table.Columns.Add("Status");
table.Columns.Add("Date Created");
table.Columns.Add("Action");
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.Parameters.Add("#username", SqlDbType.VarChar).Value = textBoxSearch.Text;
cmd.CommandText = "SELECT id,uName,uType,uStatus,uDate from users WHERE uName=#username ";
SqlDataReader dr = cmd.ExecuteReader();
if (dr.HasRows == true)
{
while (dr.Read())
{
MessageBox.Show(dr["uName"].ToString() + dr["uType"].ToString() + dr["uStatus"].ToString());
row = table.NewRow();
row["Name"] = dr["uName"].ToString();
row["Type"] = dr["uType"].ToString();
row["Status"] = dr["uStatus"].ToString();
row["Date Created"] = dr["uDate"].ToString();
// row["Action"] = new Button();
table.Rows.Add(row);
UsersView.DataSource = table;
}//End While for entering peresent amount of data
}//End If to check wether or not users exist
dr.Close();//Close Datareader
}

As you're using C#, why not go for something more LINQ-y?
Set up your LINQ Database Context file and use the following code to achieve what you're trying to (quickly typing this, sorry if there's any errors):
table = new DataTable();
table.Columns.Add("Name");
table.Columns.Add("Type");
table.Columns.Add("Status");
table.Columns.Add("Date Created");
table.Columns.Add("Action");
var db = new DbDataContext();
var users = (from u in db.users
where u.Contains(textBoxSearch.Text)
select u).ToList();
foreach(var user in users)
{
MessageBox.Show(user.uName + user.uType + user.uStatus);
row = table.NewRow();
row["Name"] = user.uName;
row["Type"] = duser.uType;
row["Status"] = user.uStatus;
row["Date Created"] = user.uDate.ToShortDateString();
table.Rows.Add(row);
}
UsersView.DataSource = table;

To call back to the database, the CommandText becomes
... WHERE uName LIKE #username + '%'
However, I wouldn't call back to the database every time: I'd use an auto complete control. There are several autocomplete controls for Winforms out there. And this SO answer too.

Related

Maintaining state of checkboxes while filtering record using textbox

I am working on a C# windows application to populate records from SQL Server to data grid view, with dynamic checkbox facility in each row. I want to select selected rows for some purpose via checkbox of that particular row. Till now I successfully achieve my target, but I'm facing a minor issue regarding saving a checked status.
For example I want to check only those records whose Name = Max. I have a textbox in that textbox I call text change event with like Query:
try
{
SqlCommand cmd = null;
SqlConnection con = null; Ranks rank = new Ranks();
con = new SqlConnection(cs.DBcon);
con.Open();
cmd = con.CreateCommand();
cmd.CommandText = "Select * from Records where Name like #Name order by Pno";
cmd.Parameters.AddWithValue("#Name", "%" + FilterByNameTextbox.Text.Trim() + "%");
SqlDataAdapter adapter1 = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
adapter1.Fill(dt);
dataGridView1.DataSource = dt;
Make_fields_Colorful();
}
catch (Exception exception)
{
MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
}
If I write Max in filter by name textbox it would return 3 records with name starts with max using like query as I mention code above. So I only check 2 records out of 3 using dynamic checkbox, till now my code runs perfectly. Now I want to check records which name starts from Ali, now when I write ali in my filter by name textbox it will return rows where name like ali , but problem comes here it will remove my previous checked records, so how I would able to save checked records for both max and ali's rows:
Code for adding dynamic checkboxes in each row
DataGridViewCheckBoxColumn checkBoxColumn = new DataGridViewCheckBoxColumn();
checkBoxColumn.Name = "checkBoxColumn";
checkBoxColumn.DataPropertyName = "Report";
checkBoxColumn.HeaderText = "Report";
dataGridView1.Columns.Insert(10, checkBoxColumn);
dataGridView1.RowTemplate.Height = 100;
dataGridView1.Columns[10].Width = 50;
Images:
Image 1
Image 2
I suggest you achieve this by caching selected rows, first you should have a list of cached rows:
List<DataGridViewRow> CachedRows = new List<DataGridViewRow>();
then add event handler on cell value change like the following:
dataGridView1.CellValueChanged += view_CellValueChanged;
and the handler should check if the column changed is the checkbox and checked, should be something like the following:
try
{
if(e.ColumnIndex == indexOfCheckBoxColumn)
{
if((bool)dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value == true)
{
CachedRows.Add((DataGridViewRow)dataGridView1.Rows[e.RowIndex].Clone());
}
else if (CachedRows.Contains(dataGridView1.Rows[e.RowIndex]))//Validate if this works, if not you should associate each row with unique key like for example (id) using a dictionary
{
CachedRows.Remove(dataGridView1.Rows[e.RowIndex]);
}
}
}
catch(Exception ex)
{
}
then after the filter changes, re-add the cached rows again, so code becomes:
try
{
SqlCommand cmd = null;
SqlConnection con = null; Ranks rank = new Ranks();
con = new SqlConnection(cs.DBcon);
con.Open();
cmd = con.CreateCommand();
cmd.CommandText = "Select * from Records where Name like #Name order by Pno";
cmd.Parameters.AddWithValue("#Name", "%" + FilterByNameTextbox.Text.Trim() + "%");
SqlDataAdapter adapter1 = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
adapter1.Fill(dt);
dataGridView1.DataSource = dt;
//add folowing
if (CachedRows.Any())
{
dataGridView1.Rows.AddRange(CachedRows.ToArray());
CachedRows.Clear();
}
Make_fields_Colorful();
}
catch (Exception exception)
{
MessageBox.Show(exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
}

Using a multiline textbox as query criteria to fill a DataGridView

This is my second question here in StackOverflow and this is where im stuck
i want to loop every value in a multiline textbox and pass it as query criteria then fill my DataGridView with the result (multiple results).
The problem is. that i cannot pass more than 1 value from the textbox. i can execute correctly the query but its not looping correctly as it only shows the result of the first value in my data grid and i want the data(result) from every line in the textbox
my code is
for (int i = 0; i < textBox1.Lines.Length; i++)
{
Connect();
OracleCommand cmd = new OracleCommand();
OracleDataAdapter adapter = new OracleDataAdapter();
DataTable dt = new DataTable();
cmd = new OracleCommand(OraSql + OraSql2 + orasql3 + OraSql4, con);
adapter = new OracleDataAdapter(cmd);
cmd.ExecuteNonQuery();
adapter.Fill(dt);
foreach (DataRow row in dt.Rows)
{
dataGridView1.Rows.Add
(
row[0].ToString(),
row[1].ToString(),
row[2].ToString(),
row[3].ToString(),
row[4].ToString(),
row[5].ToString()
);
}
}
i hope that i explained myself correctly here
Thank you!
this is my query
string OraSql = #"SELECT r.ixkitl ""Parent Part Number"",
r.ixlitm ""Component Part Number"",
i.imdsc1 ""Description"",
SUM((r.ixqnty/10000)) ""Qty per Harness"",
To_date(r.ixefff+1900000, 'YYYYDDD') ""Effective From Date"",
To_date(r.ixefft+1900000, 'YYYYDDD') ""Effective Thru Date"",
r.ixtbm ""Bill Type"",
r.ixmmcu ""Branch Plt""
FROM proddta.f3002 r,
proddta.f4101 i";
string OraSql2 = #"
WHERE (i.imlitm IN '" + textBoxX1.Text.ToString() + "'AND i.imitm = r.ixkit)";
string orasql3 = #"
AND (r.ixmmcu = ' 3320' AND r.ixtbm = 'M ')";
string OraSql4 = #"
AND r.ixefff <= (to_char(SYSDATE, 'YYYYDDD')-1900000)
AND r.ixefft >= (to_char(SYSDATE, 'YYYYDDD')-1900000)
GROUP BY r.ixkitl,
r.ixlitm,
r.ixqnty,
r.ixtbm,
r.ixmmcu,
r.ixefff,
r.ixefft,
i.imdsc1
ORDER BY r.ixkitl,
r.ixlitm";

Retrieve Rows Value to Textboxes C# & SQL Server

Do you have any ideas on how I can put this to rows:
in this texboxes?
or sooner 10 rows to 10 textboxes?
I only know is to retrieve one row:
if (Inventory.passQty == "1")
{
SqlConnection connection = new SqlConnection("Data Source = DESKTOP-ANJELLO\\SQLEXPRESS; Initial Catalog = db_ADAPurchase; Persist Security Info = True; User Id = sa; Password = mm4;");
connection.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
cmd.CommandText = String.Format("SELECT * FROM tbl_PurchaseRequest WHERE request_id = {0}", Inventory.passID);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
label_RID.Text = dr.GetString(0);
label_Item1.Text = dr.GetString(1);
txb_Title.Text = dr.GetString(2);
cbx_vendor.Text = dr.GetString(3);
txb_address.Text = dr.GetString(4);
label_date.Text = dr.GetString(5);
cbx_terms.Text = dr.GetString(6);
txb_ITD1.Text = dr.GetString(7);
txb_Qty1.Text = dr.GetSqlInt32(8).ToString();
label_unit1.Text = dr.GetString(9);
txb_UntP1.Text = dr.GetSqlInt32(10).ToString();
txb_TotP1.Text = dr.GetSqlInt32(11).ToString();
label_total.Text = dr.GetSqlInt32(12).ToString();
txb_reqBy.Text = dr.GetString(13);
}
connection.Close();
}
How do I make this to retrieve multiple rows in different textboxes?
Thanks for helping me!
PS: Sir #mohit-shrivastava can you please help me again?🙏
You can do something like this but GridView is instead a very good idea to implement this kind of situation.
if (Inventory.passQty == "1")
{
SqlConnection connection = new SqlConnection("Data Source = DESKTOP-ANJELLO\\SQLEXPRESS; Initial Catalog = db_ADAPurchase; Persist Security Info = True; User Id = sa; Password = mm4;");
connection.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandType = CommandType.Text;
cmd.CommandText = String.Format("SELECT * FROM tbl_PurchaseRequest WHERE request_id = {0}", Inventory.passID);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
label_RID.Text = dr.GetString(0);
label_Item1.Text = dr.GetString(1);
txb_Title.Text = dr.GetString(2);
cbx_vendor.Text = dr.GetString(3);
txb_address.Text = dr.GetString(4);
label_date.Text = dr.GetString(5);
cbx_terms.Text = dr.GetString(6);
label_total.Text = dr.GetSqlInt32(12).ToString();
txb_reqBy.Text = dr.GetString(13);
int number = 1;
do
{
TextBox tb = this.Controls.Find("txb_ITD" + number.ToString(), true).FirstOrDefault() as TextBox;
tb.Text = dr.GetString(7);
TextBox tb1 = this.Controls.Find("txb_Qty" + number.ToString(), true).FirstOrDefault() as TextBox;
tb1.Text = dr.GetSqlInt32(8).ToString();
TextBox tb2 = this.Controls.Find("label_unit" + number.ToString(), true).FirstOrDefault() as TextBox;
tb2.Text = dr.GetString(9);
TextBox tb3 = this.Controls.Find("txb_UntP" + number.ToString(), true).FirstOrDefault() as TextBox;
tb3.Text = dr.GetSqlInt32(10).ToString();
TextBox tb4 = this.Controls.Find("txb_TotP" + number.ToString(), true).FirstOrDefault() as TextBox;
tb4.Text = dr.GetSqlInt32(11).ToString();
number++;
//Since Query can pull more records than 10
if(number>=10)
{
break;
}
}
while(dr.Read())
}
connection.Close();
}
This code will read the SQL Data as the way you were reading it and then fill all the textboxes which are supposed to be printed once. Liek RequestID, Item, Title, Vendor etc.. then comes to the loop. Now dr already have the first record so we dont want to read the dr again otherwise it will take the next record in the record set so we used do-while instead of while. Now We are trying to find the controls from Control.ControlCollection.Find and put the extracted values to the concerning textboxes.
Note: The Code has not been tested. but it is to give you the glimpse of what has to be done to get the output as expected.
i think for creating multiple rows by creating multiple server side textbox.you neeed jquery for that. that is much easy faster and reliable:
Steps You required :
1.Create a webservice that pull all rows from the database.
2.Bind table rows by loping the data from webservice.
3.Create a webservice to insert all data to databse.

How to retrieve return row value from a SQL Server Compact database using C#.NET winform

Table with columns:
rowID, username, password, administrator,
My code:
SqlCeConnection con = new SqlCeConnection(#"Data Source=C:\Visual Studio 2010\Projects\CompactSQL\CompactSQL\DBCompact.sdf;");
con.Open();
SqlCeCommand cmd = new SqlCeCommand("SELECT * FROM DBLogin WHERE username = '" + textBox1.Text + "' AND password = '" + textBox2.Text + "'", con);
cmd.ExecuteNonQuery();
Int32 cnt = (Int32)cmd.ExecuteScalar();
MessageBox.Show(cnt.ToString());
DataTable dt = new DataTable();
SqlCeDataAdapter da = new SqlCeDataAdapter(cmd);
da.Fill(dt);
foreach (DataRowView dr in dt.Rows)
{
// how do I get the column result based on the SqlCeCommand I execute?
}
/* ex.: this only work on LinQ to SQL where I use a "foreach" to
gather up results of the column retrieved based on the
query statement executed.
foreach(var r in row)
{
id = r.rowID;
user = r.username;
pass = r.password;
access = r.access;
logID = r.logID
}
*/
I use a SQL Server Compact database for a login form what I want is that when a user login input the username and password on the text field a query is execute to compare if a user exist on the compact db and when found return back the username, access, and logid in a loop with a count of how many row record exist.
Try this
foreach (DataRow dr in dt.Rows)
{
id = dr["rowID"].ToString();
user = dr["username"].ToString();;
pass = dr["password"].ToString();;
access = dr["access"].ToString();;
logID = dr["logID"].ToString();
}
You may need to convert some values to their appropriate type like Id and logID looks to be int type.
using linq: you can query the DataTable's Rows collection by adding AsEnumerable() extension. Like so:
var row = from rw in dt.AsEnumerable()
select new { id = rw.Field<long>("rowID"),
user = rw.Field<string>("username"),
pass = rw.Field<string>("password"),
access = rw.Field<int>("access"),
logID = rw.Field<int>("logID")};
/* ex.: this only work on LinQ to SQL where I use a "foreach" to
gather up results of the column retrieved based on the
query statement executed.
if(row.Any())
{
foreach(var r in row)
{
id = r.id;
user = r.user;
pass = r.pass;
access = r.access;
logID = r.logID
}
}
*/

trying to get table recoreds to datagrid view one by one

this is my code but this is giving last record only. but i need all records one by one
string query = "select * from tbl_users;";
SqlCommand com = new SqlCommand(query, con);
con.Open();
SqlDataReader reader = com.ExecuteReader();
for (int x = 0; x <= total; x++)
{
dataGridView1.Rows.Add();
while (reader.Read())
{
dataGridView1.Rows[x].Cells["colNic"].Value = reader["NIC"].ToString();
dataGridView1.Rows[x].Cells["colName"].Value = reader["name"].ToString();
dataGridView1.Rows[x].Cells["colAge"].Value = reader["age"].ToString();
dataGridView1.Rows[x].Cells["colCity"].Value = reader["city"].ToString();
}
}
con.Close();
What i undestand from the above is that you actually want to add each record in datagridview as row, so the following should be the code for that:
string query = "select * from tbl_users;";
SqlCommand com = new SqlCommand(query, con);
con.Open();
SqlDataReader reader = com.ExecuteReader();
while (reader.Read())
{
int x = dataGridView1.Rows.Add(); // add new row for each db row in grid
// and use index returned by it
DataGridViewRow currentRow = dataGridView1.Rows[x];
currentRow.Cells["colNic"].Value = reader["NIC"].ToString();
currentRow.Cells["colName"].Value = reader["name"].ToString();
currentRow.Cells["colAge"].Value = reader["age"].ToString();
currentRow .Cells["colCity"].Value = reader["city"].ToString();
}
dataGridView1.Rows.Add() will return the index back for the newly created row, so you should be using that, you actually do not need that for loop, just iterate all the returned row using while and keep adding row in grid one by one.
Another suggestion here is that do not use * when selecting records from the table if you only need specific columns, always specify the columns that you need in the query like:
SELECT NIC,name,age,city FROM tbl_users
Hope it helps.

Categories

Resources