Binding search results to data grid - c#

I want to add search functionality to my program. There's a class which has this function:
public DataTable Search()
{
string SQL = "Select * from Customer where " + mField + " like '%" + mValue + "%'";
DataTable dt = new DataTable();
dt = dm.GetData(SQL);
return (dt);
}
There are setter and getter properties for mField and mValue. DM is the object of class DataManagement, which has a method GetData:
public DataTable GetData(string SQL)
{
SqlCommand command = new SqlCommand();
SqlDataAdapter dbAdapter = new SqlDataAdapter();
DataTable DataTable = new DataTable();
command.Connection = clsConnection.GetConnection();
command.CommandText = SQL;
dbAdapter.SelectCommand = command;
dbAdapter.Fill(DataTable);
return (DataTable);
}
The search functionality is currently implemented like this:
private void btnfind_Click(object sender, EventArgs e)
{
//cust is the object of class customer//
if (tbCustName.Text != "")
{
cust.Field="CustName";
cust.Value = tbCustName.Text;
}
else if (tbAddress.Text != "")
{
cust.Value = tbAddress.Text;
cust.Field="Address";
}
else if (tbEmail.Text != "")
{
cust.Value = tbEmail.Text;
cust.Field="Email";
}
else if (tbCell.Text != "")
{
cust.Value = tbCell.Text;
cust.Field = "Cell";
}
DataTable dt = new DataTable();
dt = cust.Search();
dgCustomer.DataSource = dt;
RefreshGrid();
}
private void RefreshGrid()
{
DataTable dt = new DataTable();
dt = cust.GetCustomers();
dgCustomer.DataSource = dt;
}
This is not working. I don't know why. Please help.

Add a DataBind() statement in your RefreshGrid() method to have your new results actually shown on the Grid.
private void RefreshGrid()
{
DataTable dt = cust.GetCustomers();
dgCustomer.DataSource = dt;
dgCustomer.DataBind();
}
Consider modifying your other method as well:
Your ad-hoc SQL has a SQL injection vulnerability. Stop everything until you fix that!
btnfind_Click doesn't need to end up calling cust.Search() twice.
private void btnfind_Click(object sender, EventArgs e)
{
//<snip>
// no need to do all this twice.
// DataTable dt = new DataTable();
// dt = cust.Search();
// dgCustomer.DataSource = dt;
RefreshGrid();
}

Your RefreshGrid method is overwriting the DataSource you set in btnfind_Click... don't call it, just call DataBind
private void btnfind_Click(object sender, EventArgs e)
{
...
DataTable dt = cust.Search();
dgCustomer.DataSource = dt;
dgCustomer.DataBind();
}
By the way, you don't need to assign a new DataTable to dt if you're immediately setting it to the result of cust.Search... you're just creating an instance for nothing (I fixed it in the code above)

Related

Whats is proper way of using RowFilter on DataGridView populated with DataTable?

I have followed method from this SO post to perform search on datagridview
Below is my attempt. I would like to stop querying database with DgvSearch() method on text change, instead use RowFilter.
Within current attempt, datagridview is properly populated from LoadDataParts(), when i start typing in TxtPP_GBC2, i see only column header, no exception is thrown.
GBC column is defined as "INT".
Expected result -> TxtPP_GBC2_TextChanged() will behave same like DgvSearch()
public partial class ProgramPart : Form
{
public SqlConnection Con { get; } = new SqlConnection(#"***");
public string UserDBO;
private DataTable dataTable = new DataTable();
public ProgramPart()
{
InitializeComponent();
LoadDataParts();
}
public void LoadDataParts()
{
string sql3 = "SELECT * FROM Parts";
SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sql3, Con);
sqlDataAdapter.Fill(dataTable);
sqlDataAdapter.Dispose();
dataGridView1n.DataSource = dataTable;
}
private void TxtPP_GBC2_TextChanged(object sender, EventArgs e)
{
//DgvSearch(); //////// DgvSearch() works perferctly
try
{
if(txtPP_GBC2.Text == "")
{
dataTable.Clear();
LoadDataParts();
dataGridView1n.Refresh();
return;
}
(dataGridView1n.DataSource as DataTable).DefaultView.RowFilter = "GBC = '" + Convert.ToInt32(txtPP_GBC2.Text) + "'";
dataGridView1n.Refresh();
}
catch(Exception s)
{
MessageBox.Show(s.ToString());
}
}
private void DgvSearch()
{
string sql3 = "SELECT * FROM Parts WHERE GBC LIKE #GBC2 AND Description LIKE #DES";
Con.Open();
SqlDataAdapter da = new SqlDataAdapter(sql3, Con);
da.SelectCommand.Parameters.AddWithValue("#GBC2", SqlDbType.Int).Value = "%" + txtPP_GBC2.Text + "%";
da.SelectCommand.Parameters.AddWithValue("#DES", SqlDbType.VarChar).Value = "%" + txtPP_Description2.Text + "%";
DataSet ds = new DataSet();
da.Fill(ds, "Parts");
da.Dispose();
dataGridView1n.DataSource = ds;
dataGridView1n.DataMember = "Parts";
Con.Close();
}
}
You can use Convert expression function to convert value of the int column to the string and compare it using such filter:
private DataTable LoadData()
{
var dt = new DataTable();
dt.Columns.Add("C1", typeof(int));
dt.Rows.Add(1);
dt.Rows.Add(11);
dt.Rows.Add(2);
dt.Rows.Add(22);
return dt;
}
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.DataSource = LoadData();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
var filter = "";
if (!string.IsNullOrEmpty(textBox1.Text))
filter = $"Convert([C1], System.String) = '{textBox1.Text}'";
(dataGridView1.DataSource as DataTable).DefaultView.RowFilter = filter;
}
If for any reason you prefer LIKE operator, you need to change the filter to:
filter = $"Convert([C1], System.String) LIKE '%{textBox1.Text}%'";

c#.net code for retrive data from dataset or datatable object

I have created a class file. In that class file, i have created a method name as getdata of type dataset or datatable. This method is to retrieve/fetch data from database and return dataset or datatable object.
I want to display data from dataset or datatable object using combobox event into textboxes.
private void comboBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
try
{
DataOperation DO = new DataOperation();
//DataSet DS = new DataSet();
// DS = DO.GetCompnyDetails(Convert.ToInt32(CmBxCompanyName.Text),
"SelectById");
//txtCompanyId.Text = DS.Tables[0].Rows[0["c_id"].ToString();
//txt_mno.Text = DS.Tables[0].Rows[0]["cont_no"].ToString();
//txt_add.Text = DS.Tables[0].Rows[0]["address"].ToString();
//txt_vno.Text = DS.Tables[0].Rows[0]["vat_no"].ToString();
//txtCstNo.Text = DS.Tables[0].Rows[0]["CSTNo"].ToString();
//txt_eid.Text = DS.Tables[0].Rows[0]["e_id"].ToString();
}
}
private void comboBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
try
{
DataOperation DO = new DataOperation();
DataTable Dt;
Dt = DO.GetPymntDetails(Convert.ToInt32(CmBxCompanyName.Selected Index), "SelectById");
if (Dt != null)
{
txtCompanyId.Text = Dt.Rows[0].ItemArray[0].ToString();
txt_mno.Text = Dt.Rows[0].ItemArray[1].ToString();
txt_add.Text = Dt.Rows[0].ItemArray[2].ToString();
txt_vno.Text = Dt.Rows[0].ItemArray[3].ToString();
txtCstNo.Text = Dt.Rows[0].ItemArray[4].ToString();
txt_eid.Text = Dt.Rows[0].ItemArray[5].ToString();
}
}
}
if (Dt.Rows.Count > 0)
{
txtCompanyId.Text = Dt.Rows[0][0].ToString();
txt_mno.Text = Dt.Rows[0][1].ToString();
txt_add.Text = Dt.Rows[0][2].ToString();
txt_vno.Text = Dt.Rows[0][3].ToString();
txtCstNo.Text = Dt.Rows[0][4].ToString();
txt_eid.Text = Dt.Rows[0][5].ToString();
}

unable to bind data with dropdown list?

I am making an application in asp.net using C# which contains drop down list.Now I don't want to write same code for fetching same data from database.I am try this code but it's not working
protected void Page_Load(object sender, EventArgs e)
{
DataTable DT = sel_obj.select_Dept_Name();
departmentDrop.DataSource = DT;
departmentDrop.DataMember = "Department_Name";
departmentDrop.DataBind();
}
public DataTable select_Dept_Name()
{
module c = new module();
c.DB_Connection();
if (c.con.State == ConnectionState.Open)
{
c.con.Close();
c.con.Open();
}
DataSet DS = new DataSet();
string QRY = "";
QRY = "SELECT Department_Name FROM Department_Master";
SqlDataAdapter DA = new SqlDataAdapter(QRY, c.con);
DA.Fill(DS);
DataTable DT = DS.Tables[0];
return DT;
}
You need to call "DataBind()" function. You need to also make sure that your table contains data to bind with dropdown list.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DataTable DT = sel_obj.select_Dept_Name();
departmentDrop.DataSource = DT ;
departmentDrop.DataTextField = "Department_Name";
departmentDrop.DataValueField = "Department_Name";
departmentDrop.DataBind();
}
}

Copy gridview rows in another gridview on a button_click

I have a textBox and a search button that fills the first Gridview. After that a Second Button Copies the first grid rows in the second grid . After that i should be able to search again in the first grid and attach the other results to the second grid.
But i get an error. Thnx in advance.
Here is my code:
public partial class Grid: System.Web.UI.Page
{
DataTable Dt = new DataTable();
private DataTable Dt1
{
set { ViewState.Add("Dt1", value); }
get { return (DataTable)ViewState["Dt1"]; }
}
private void Fill_grid()
{
string query = "Select * from table " +
" where field1 like '" + TextBox1.Text + "' or filed2 like '" +TextBox1.Text + "'";
SqlConnection cnn = new SqlConnection(...);
SqlCommand cmm = new SqlCommand(query,cnn);
cmm.CommandType = System.Data.CommandType.Text;
SqlDataAdapter MyDataAdapter = new SqlDataAdapter(cmm);
DataSet DS = new DataSet();
cnn.Open();
MyDataAdapter.Fill(DS, "Client");
Dt1 = DS.Tables["klient"];
DataView dv = new DataView(Dt1);
GridView2.DataSource = DS.Tables["klient"].DefaultView;
GridView2.DataBind();
}
protected void Button2_Click(object sender, EventArgs e)
{
Fill_grid();
}
protected void Button1_Click(object sender, EventArgs e)
{
Fill_Second_Grid();
}
private void Fill_Second_Grid()
{
DataRow dr;
foreach (GridViewRow row in GridView2.Rows)
{
dr = Dt.NewRow();
dr["Email"] = row.Cells[0].Text; ;
Dt.Rows.Add(dr);
}
GridView3.DataSource = Dt;
GridView3.DataBind();
}
}

Select a DataRow in a DataGridView after creating new row

I use a PostgreSQL view to display data in a DataGridView:
dataSource = new BindingSource();
dataSource.DataSource = Program.DB.GetView(dbView); // returns a DataTable
dgData.DataSource = dataSource;
Now, after I added a record using a PostgreSQL function, I refresh the data in the grid (I don't call Rows.Add() on the DataGridView:
protected void RefreshData() {
dataSource.DataSource = Program.DB.GetView(dbView);
}
The insertion function of PostgreSQL returns the ID of the inserted row, so I know the ID (which is primary key) and want to set Selected to true in the DataGridView. The row can be anywhere in the set, because the view is sorted by name, not ID. I reckon I could do that by cycling over all rows and set the Selected when I found it, but this could become slow on large datasets.
Is there a way to somehow bind the rows of the datasource to the datagrid?
Add an event handler to the ListChanged event:
dataSource.ListChanged += dataSource_ListChanged;
Here is the event handler definition:
void dataSource_ListChanged(object sender, ListChangedEventArgs e)
{
if (dgData.Rows.Count > 0)
dgData.CurrentCell = dgData.Rows[e.NewIndex].Cells[0];
}
[UPDATE]
As I also suggested in the comments, maybe you should not repopulate the data source on each insert (or update). To demonstrate my point, I'll post a code sample which uses a DataGridView, 2 TextBoxes and 2 Buttons (for insert and update) and a SqlDataAdapter. The SQL table has 2 columns (id and value).
Here's the code (I didn't cover the deletion):
public partial class Form1 : Form
{
static BindingSource dataSource;
static string dbView = "default";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
dgData.MultiSelect = false;
dataSource = new BindingSource();
dataSource.ListChanged += dataSource_ListChanged;
RefreshData();
dgData.DataSource = dataSource;
dgData.Sort(dgData.Columns[1], ListSortDirection.Ascending);
}
void dataSource_ListChanged(object sender, ListChangedEventArgs e)
{
if (dgData.Rows.Count > 0)
dgData.CurrentCell = dgData.Rows[e.NewIndex].Cells[0];
}
protected void RefreshData()
{
dataSource.DataSource = DB.GetView(dbView);
}
private void insert_Click(object sender, EventArgs e)
{
DB.Insert(textBox1.Text);
RefreshData();
}
private void update_Click(object sender, EventArgs e)
{
DB.UpdateRandomRow(textBox2.Text);
RefreshData();
}
}
class DB
{
static DataTable dt;
static string conStr = "yourConnectionString";
static SqlDataAdapter _adapter;
static Random r = new Random(10);
public static SqlDataAdapter CreateSqlDataAdapter(SqlConnection connection)
{
_adapter = new SqlDataAdapter();
_adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
_adapter.SelectCommand = new SqlCommand(
"SELECT * FROM test", connection);
_adapter.InsertCommand = new SqlCommand(
"INSERT INTO test (value) " +
"VALUES (#value)", connection);
_adapter.UpdateCommand = new SqlCommand(
"UPDATE test SET [value] = #value " +
"WHERE id = #id", connection);
_adapter.InsertCommand.Parameters.Add("#value",
SqlDbType.NVarChar, 50, "value");
_adapter.UpdateCommand.Parameters.Add("#id",
SqlDbType.Int, 4, "id").SourceVersion = DataRowVersion.Current;
_adapter.UpdateCommand.Parameters.Add("#value",
SqlDbType.NVarChar, 50, "value").SourceVersion = DataRowVersion.Current;
return _adapter;
}
// random update, to demonstrate dynamic
// repositioning
public static DataTable UpdateRandomRow(string value)
{
var currentRandom = r.Next(dt.Rows.Count);
dt.Rows[currentRandom].SetField<string>(1, value);
using (var con = new SqlConnection(conStr))
{
con.Open();
_adapter = CreateSqlDataAdapter(con);
_adapter.Update(dt);
}
return dt;
}
internal static DataTable GetView(string dbView)
{
if (dt == null)
{
dt = new DataTable();
using (var con = new SqlConnection(conStr))
{
con.Open();
_adapter = CreateSqlDataAdapter(con);
_adapter.Fill(dt);
}
}
return dt;
}
internal static void Insert(string value)
{
if (dt == null)
GetView("");
var dr = dt.NewRow();
dr[1] = value;
dt.Rows.Add(dr);
using (var con = new SqlConnection(conStr))
{
con.Open();
_adapter = CreateSqlDataAdapter(con);
_adapter.Update(dt);
}
}
}
If you test it, you'll see that the request from your question is satisfied for both insert and update. Also, please note the performance improvement, as the data table is not recreated on each operation.

Categories

Resources