I have a form that displays a datagridview and a textbox and combobox. When a column name is selected in the combobox, and a search typed in the textbox it filters and displays the searched data.
How can I detect if the combobox has nothing selected, and change the textbox readonly state to true, and when something is selected, change it back to false so I can search?
DataTable dt;
private void searchForm_Load(object sender, EventArgs e)
{
SqlCeConnection con = new SqlCeConnection(#"Data Source=|DataDirectory|\LWADataBase.sdf;");
SqlCeDataAdapter sda = new SqlCeDataAdapter("select * from customersTBL", con);
dt = new DataTable();
sda.Fill(dt);
dataGridView1.DataSource = dt;
comboSearch.Items.Add("[First Name]");
comboSearch.Items.Add("Surename");
comboSearch.Items.Add("[Address Line 1]");
comboSearch.Items.Add("[Address Line 2]");
comboSearch.Items.Add("County");
comboSearch.Items.Add("[Post Code]");
comboSearch.Items.Add("[Contact Number]");
comboSearch.Items.Add("[Email Address]");
}
private void searchTxt_TextChanged(object sender, EventArgs e)
{
{
DataView dv = new DataView(dt);
dv.RowFilter = "" + comboSearch.Text.Trim() + "like '%" + searchTxt.Text.Trim() + "%'";
dataGridView1.DataSource = dv;
}
}
You can try this
if( ComboBox.SelectedItem == null ) {
// do something
TextBox.ReadOnly = true; //Using the TextBox.ReadOnly property
}
else{
Textbox.ReadOnly=false;
}
hope it helps you!
Add a row in your FormLoad to the comboSearch control for a blank line. Make sure it's about the [First Name] item.
comboSearch.Items.Add(string.Empty);
comboSearch.Items.Add("[First Name]");
Add an event handler to comboSearch for SelectedIndexChanged. Inside the event, set the searchTxt control's ReadOnly property. It may look like this:
private void comboSearch_SelectedIndexChanged(object sender, EventArgs e)
{
searchTxt.ReadOnly = comboSearch.SelectedIndex != 0;
}
I added a SelectedIndexChanged event:
private void comboSearch_SelectedIndexChanged(object sender, EventArgs e)
{
searchTxt.ReadOnly = false;
}
And changed the TextChanged event to:
private void searchTxt_TextChanged(object sender, EventArgs e)
{
if (comboSearch.SelectedItem == null)
{
searchTxt.ReadOnly = true;
MessageBox.Show("Please select a search criteria");
}
else
{
searchTxt.ReadOnly = false;
DataView dv = new DataView(dt);
dv.RowFilter = "" + comboSearch.Text.Trim() + "like '%" + searchTxt.Text.Trim() + "%'";
dataGridView1.DataSource = dv;
}
}
and it now functions how I'd like it to
Add an empty item to the combobox and then
if(comboSearch.SelectedItem =="")
{
searchTxt.ReadOnly = true;
}
else
{
searchTxt.ReadOnly = false;
}
After executing your code add this line:
comboSearch.SelectedIndex =0;
Make sure your empty item is the first item.
Related
I have a dataGridView and have logs inside it. I wanted to filter by time and number and name. There is no problem in working separately. When the textbox and datetimepicker are filtered together, I get the error that the variable of type bindingsource unable to be cast to dataview. how do i solve this problem?
I'm not printing the lines between two dates, I'm directly filtering the date written in the flight_date column. gridFilter = datagridview
private void timeFilter_ValueChanged(object sender, EventArgs e)
{
try
{
if (File.Exists(inputpath))
{
DataTable dt = (DataTable)gridFilter.DataSource;
DataView dv = new DataView();
dv = dt.DefaultView;
dv.RowFilter = "Flight_Date >= '" + timeFilter.Value.Date + "' and Flight_Date <= '" +
timeFilter.Value.Date + "'";
}
}
catch(System.InvalidCastException ex)
{
MessageBox.Show(ex.ToString());
}
}
private void txt_filterNum_TextChanged(object sender, EventArgs e)
{
if (File.Exists(inputpath))
{
BindingSource bs = new BindingSource();
bs.DataSource = gridFilter.DataSource;
bs.Filter = gridFilter.Columns[indexRoleNum].HeaderText.ToString() + " LIKE '%" + Convert.ToString(txt_filterNum.Text) + "%'";
gridFilter.DataSource = bs;
}
}
Assuming that the bind has been done correctly, i.e. a DataTable to a BindingSource to the grid, you could filter the data like this:
private void timeFilter_ValueChanged(object sender, EventArgs e)
{
SetFilter();
}
private void txt_filterNum_TextChanged(object sender, EventArgs e)
{
SetFilter();
}
private void SetFilter()
{
myBindingSource.Filter = $"Flight_Date = #{timeFilter.Value:M/dd/yyyy}# AND {gridFilter.Columns[indexRoleNum].HeaderText} LIKE '%{txt_filterNum.Text}%'";
}
As I suggested in the comments, it may provide a better experience if you implement a delay between the text changing and the filtering being done:
private void timeFilter_ValueChanged(object sender, EventArgs e)
{
SetFilter();
}
private void txt_filterNum_TextChanged(object sender, EventArgs e)
{
filterTimer.Stop();
filterTimer.Start();
}
private void filterTimer_Tick(object sender, EventArgs e)
{
filterTimer.Stop();
SetFilter();
}
private void SetFilter()
{
myBindingSource.Filter = $"Flight_Date = #{timeFilter.Value:M/dd/yyyy}# AND {gridFilter.Columns[indexRoleNum].HeaderText} LIKE '%{txt_filterNum.Text}%'";
}
I want to filter my grid view according to inputs from two text boxes.
What I have:
private void textBox1_TextChanged_1(object sender, EventArgs e)
{
(dataGridView1.DataSource as DataTable).DefaultView.RowFilter = string.Format("[1] LIKE '%{0}%'", textBox1.Text);
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
(dataGridView1.DataSource as DataTable).DefaultView.RowFilter = string.Format("[2] LIKE '%{0}%'", textBox2.Text);
}
for example the first column is "123" and second column is "clark".
In addition to setting the value of RowFilter you also need to bind the data to the gridview (again), so that it is updated on the UI.
So, you need to assign the data source, and call DataBind() on the grid - in both the methods. Like this,
GridViewMain.DataSource = dataView;
GridViewMain.DataBind();
I did it my self but thanks all of you who trying to help me. :)
private void textBox1_TextChanged_1(object sender, EventArgs e)
{
(dataGridView1.DataSource as DataTable).DefaultView.RowFilter = string.Format("[1] LIKE '%" + textBox1.Text + "%' and [2] like '%" + textBox2.Text + "%'");
}
Use this snippet to achieve what you need
DataSet ds = new DataSet();
SqlConnection myCon = new SqlConnection(connectionstring);
SqlDataAdapter adapter = new SqlDataAdapter(cmd, myCon);
adapter.Fill(ds);
DataView view = new DataView();
view.Table = ds.Tables[0];
view.RowFilter = "ColumnName = " + TextBox1.Text.Trim();
GridView1.DataSource = view;
GridView1.DataBind();
this is done using ADO.Net.
Edit to match your question:
private void Form1_Load(object sender, EventArgs e)
{
DataTable resultTable = new DataTable();
string path = #"\\192.168.96.80\hrmspics";
recFolders(path, ref resultTable);
dataGridView1.DataSource = resultTable;
dataGridView1.DataBind();
From official Microsoft MSDN:
Use the DataBind() method to bind data from a data source to the GridView control. This method resolves all data-binding expressions in the active template of the control.
I have 2 grids in a form. One grid is filled with some Students info. And I want that when I put the Mouse over the dataGridview1, to show the other gridview like a Popup or something like that, and populate the other datagridview with informatin based on the Name column.
I did the part where the grid shows as a popup and follows the mouse. Also when it leaves the grid it will disappear:
private void dataGridView1_MouseHover(object sender, EventArgs e)
{
SqlDataAdapter da2;
DataTable dt2 = new DataTable();
da2 = new SqlDataAdapter("SELECT ID, Name, Surname, City"+
"FROM tblStudents2" +
"WHERE Name = **what to write here**", con);
da2.Fill(dt2);
dataGridView2.DataSource = dt2;
}
private void dataGridView1_MouseLeave(object sender, EventArgs e)
{
dataGridView2.Visible = false;
}
private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
{
dataGridView2.Visible = true;
dataGridView2.Location = new Point(MousePosition.X-100, MousePosition.Y-100);
}
I just want to ask you, what to write i the SQL Statement, at the part: WHERE Name='____' ??
I want that when the Mous is over the first Row, to take the Name (column index 1) and populate the other datagrid.
I hope you understand me :(
****EDITED
Here is my code after going through the Code Of Ehsan... It workes almost. The problem is it doesn't Repopulate the grid after moving the mouse to the next row!! Butif I leave the DataGrid, and put the mouse to the other Row, it shows me the ifnormation of this row. How to make something lik a refresh grid after moving the mouse to the next row??
public void LoadGridi2()
{
SqlDataAdapter da2;
DataTable dt2 = new DataTable();
da2 = new SqlDataAdapter("SELECT ID, Name, Surname, City FROM tblMentori WHERE Name = '" + dataGridView1.Rows[row.Index].Cells[1].Value.ToString() + "'", con);
da2.Fill(dt2);
dataGridView2.DataSource = dt2;
}
private void dataGridView1_MouseHover(object sender, EventArgs e)
{
LoadGridi2();
}
private void dataGridView1_MouseLeave(object sender, EventArgs e)
{
dataGridView2.Visible = false;
}
DataGridViewRow row;
private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
{
dataGridView2.Visible = true;
dataGridView2.Location = new Point(MousePosition.X - 100, MousePosition.Y - 100);
}
private void dataGridView1_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.RowIndex >= 0)
{
row = (DataGridViewRow)dataGridView1.Rows[e.RowIndex];
}
}
You should do this. Bind to the CellMouseMove event of grid.
private void dataGridView1_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.RowIndex >= 0)
{
DataGridViewRow row = DataGridViewRow)dataGridView1.Rows[e.RowIndex];
SqlDataAdapter da2;
DataTable dt2 = new DataTable();
da2 = new SqlDataAdapter("SELECT ID, Name, Surname, City FROM tblStudents2 WHERE Name = '" + row["Name"].Value.ToString()+ "'", con);
da2.Fill(dt2);
dataGridView2.DataSource = dt2;
}
}
and
e.RowIndex
is the index you are looking for
Use CellMouseMove event. You can get item which is bound to current row (e.g. some Person instance):
void dataGridView1_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.RowIndex < 0)
return;
DataGridView grid = (DataGridView)sender;
var person = (Person)grid.Rows[e.RowIndex].DataBoundItem;
var name = person.Name;
}
Here is full code (I use label control for simplicity):
// this field used to avoid loading data which you already have
private Person currentPerson;
void dataGridView1_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.RowIndex < 0)
{
HidePersonDetails();
return;
}
DataGridView grid = (DataGridView)sender;
var person = grid.Rows[e.RowIndex].DataBoundItem as Person;
if (person == null)
{
HidePersonDetails();
return;
}
var rectangle = grid.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true);
var cellLocation = rectangle.Location;
var detailsLocation = new Point(e.X + cellLocation.X,
e.Y + cellLocation.Y + rectangle.Height);
ShowPersonDetails(person, detailsLocation);
}
private void dataGridView1_MouseLeave(object sender, EventArgs e)
{
HidePersonDetails();
}
private void ShowPersonDetails(Person person, Point location)
{
if (currentPerson != person)
{
// get data from SQL server
// set datasource of your details grid
currentPerson = person;
}
label1.Text = person.Name;
label1.Location = location;
label1.Show();
}
private void HidePersonDetails()
{
label1.Hide();
}
I have 2 comboboxes named cBTeam1 and cBTeam2 (winForm & C#) both are bound from same database table.
If a person selects a team from cBTeam1, I want this selected team to not be displayed in cBTeam2.
private void bindComboBox()
{
if (con.State == ConnectionState.Closed)
{
con.Open();
}
string queryTeam1 = "SELECT * FROM Teams ORDER BY Team_name";
SqlCommand cmd = new SqlCommand(queryTeam1, con);
adapter = new SqlDataAdapter(cmd);
adapter.Fill(ds, "Teams");
this.cBoxTeam1.SelectedIndexChanged -= new EventHandler(this.cBoxTeam1_SelectedIndexChanged);
cBoxTeam1.DataSource = ds.Tables["Teams"];
//if(cBoxTeam1.SelectedIndex
cBoxTeam1.DisplayMember = "Team_name";
cBoxTeam1.SelectedIndex = -1;
cBoxTeam1.ValueMember = "team_id";
this.cBoxTeam1.SelectedIndexChanged += new EventHandler(this.cBoxTeam1_SelectedIndexChanged);
}
and here is code for cBoxTeam2 event handler cBoxTeam2_SelectedIndexChanged
private void cBoxTeam2_SelectedIndexChanged(object sender, EventArgs e)
{
if (cBoxTeam1.SelectedIndex == cBoxTeam2.SelectedIndex)
{
MessageBox.Show("You already selected " + cBoxTeam2.Text);
}
team2_id = Int32.Parse(cBoxTeam2.SelectedValue.ToString());
}
For example cBoxTeam1 displaye 3 values i.e England, India, Austrailia.
if I Select India, after selection India shold not be display in the cBoxTeam2 combobox
Hey i have made sample for you.Sample have 2 combo box and bind same data source.And when I select combobox1 firstly check with list if exist bind combobox 2 except matched item.
protected List<string> lst
{
get
{
List<string> lst =
new List<string>();
lst.Add("1");
lst.Add("2");
lst.Add("3");
return lst;
}
}
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.DataSource = lst;
comboBox2.DataSource = lst;
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (lst.Contains(comboBox1.SelectedItem.ToString()))
{
comboBox2.DataSource = lst.Select(q => q.ToString(CultureInfo.InvariantCulture)).Where(q => q.ToString() != comboBox1.SelectedItem).ToList();
}
}
Try this
public void loadcBTeam1()
{
....
string queryTeam1 = "SELECT Team_name FROM Teams where Team_name <> '" + yourComboBox2.text + "' ORDER BY Team_name";
......
}
and on your ComboBox2 TextChanged
private void comboBox2_TextChanged(object sender, EventArgs e)
{
loadcBTeam1();
}
I'm working on datagridview in c# windows forms application and I'm loading the data from the database, now i want the user to be able to able to edit the cell value and save the value to the database, how to edit the cell value and how can i save the value to the database?
SqlConnection con = new SqlConnection("user id=sa;password=123;database=employee");
SqlDataAdapter da = new SqlDataAdapter("select * from UserReg", con);
DataSet ds = new DataSet();
da.Fill(ds, "p");
dataGridView1.DataSource = ds.Tables["p"];
One of the way to update a database with DataGridView is using of DataGridView's events:
DataGridView.CellBeginEdit
DataGridView.CellValidating
DataGridView.CellEndEdit
Let say: private DataGridView dgv;
Add handlers of events
dgv.CellBeginEdit += dgv_CellBeginEdit;
dgv.CellValidating += dgv_CellValidating;
dgv.CellEndEdit += dgv_CellEndEdit;
private void dgv_CellBeginEdit(Object sender, DataGridViewCellCancelEventArgs e)
{
//Here we save a current value of cell to some variable, that later we can compare with a new value
//For example using of dgv.Tag property
if(e.RowIndex >= 0 && e.ColumnIndex >= 0)
{
this.dgv.Tag = this.dgv.CurrentCell.Value;
//Or cast sender to DataGridView variable-> than this handler can be used in another datagridview
}
}
private void dgv_CellValidating(Object sender, DataGridViewCellValidatingEventArgs e)
{
//Here you can add all kind of checks for new value
//For exapmle simple compare with old value and check for be more than 0
if(this.dgv.Tag = this.dgv.CurrentCell.Value)
e.Cancel = true; //Cancel changes of current cell
//For example used Integer check
int32 iTemp;
if (Int32.TryParse(this.dgv.CurrentCell.Value, iTemp) = True && iTemp > 0)
{
//value is ok
}
else
{
e.Cancel = True;
}
}
Private Sub dgvtest1_CellEndEdit(Object sender, DataGridViewCellEventArgs e)
{
//Because CellEndEdit event occurs after CellValidating event(if not cancelled)
//Here you can update new value to database
}
Try to do this:
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
//after you've filled your ds, on event above try something like this
try
{
da.Update(ds);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I used OleDb but you can use SQL. Here is the code I usually use for the same.
OleDbCommand sCommand;
OleDbDataAdapter sAdapter;
OleDbCommandBuilder sBuilder;
OleDbConnection connection;
DataSet sDs;
DataTable sTable;
string myMode = "";
private void BtnLoad_Click(object sender, EventArgs e)
{
string query = "SELECT * FROM [Table]";
connection = new OleDbConnection(connectionString);
connection.Open();
sCommand = new OleDbCommand(query, connection);
sAdapter = new OleDbDataAdapter(sCommand);
sBuilder = new OleDbCommandBuilder(sAdapter);
sDs = new DataSet();
sAdapter.Fill(sDs, "Table");
sTable = sDs.Tables["Table"];
connection.Close();
DataGrid.DataSource = sTable;
DataGrid.ReadOnly = true;
DataGrid.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
}
private void BtnAdd_Click(object sender, EventArgs e)
{
DataGrid.ReadOnly = false;
myMode = "add";
}
private void BtnEdit_Click(object sender, EventArgs e)
{
DataGrid.ReadOnly = false;
myMode = "edit";
}
private void BtnDelete_Click(object sender, EventArgs e)
{
myMode = "";
if (MessageBox.Show("Do you want to delete this row ?", "Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
DataGrid.Rows.RemoveAt(DataGrid.SelectedRows[0].Index);
sAdapter.Update(sTable);
}
}
private void BtnSave_Click(object sender, EventArgs e)
{
if (myMode == "add")
{
sAdapter.Update(sTable);
MessageBox.Show("Prices Are Successfully Added.", "Saved.", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
}
else if (myMode == "edit")
{
string query = "UPDATE Table_Name SET " +
"Column1 = '" + DataGrid.SelectedRows[0].Cells[0].Value.ToString() + "' ," +
"Column2 = " + DataGrid.SelecteddRows[0].Cells[1].Value.ToString() + ", " +
"WHERE CONDITION";
connection = new OleDbConnection(connectionString);
connection.Open();
sCommand = new OleDbCommand(query, connection);
sAdapter = new OleDbDataAdapter(sCommand);
sBuilder = new OleDbCommandBuilder(sAdapter);
sDs = new DataSet();
sAdapter.Fill(sDs, "Table");
sTable = sDs.Tables["Table"];
connection.Close();
DataGrid.DataSource = sTable;
DataGrid.ReadOnly = true;
}
}
Have a look at the DataGridView Events list. You need to subscribe to the appropriate event, and handle it accordingly. Namely, you're interested in DataGridView.CellValueChanged.
dataGridView1.CellValueChanged += ValueChangedHandler;
private void ValueChangedHandler(object sender, DataGridViewCellEventArgs e) {
// do what is appropriate here.
}
Add this line of code to enable editing on datagridview
dtg.EditMode = DataGridViewEditMode.EditOnKeystroke;
Then use below event
private void dtg_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.ColumnIndex > -1 && e.RowIndex > -1)
{
dtg.ReadOnly = false;
}
}
The above two events will enable editing in datagridview.
Then use below event to save the updated data back to db.
private void dtg_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
}