I added Checkboxcolumn near my columns.
i googling a lot but i cant find a good answer.
I Want to make Btn_Edit.Visiable=false; if checkbox checked count is up to 1.
after my researches i go to Use CellContentClick event but it isn't work fine.
My Code:
private void GrdVw_Reception_CellContentClick_1(object sender, DataGridViewCellEventArgs e)
{
if (GrdVw_Reception.CurrentCellAddress.X == 0)
{
int UpTpOne = 0;
bool flag = false;
for (int i = 0; i < GrdVw_Reception.Rows.Count; i++)
{
if (Convert.ToBoolean(GrdVw_Reception.Rows[i].Cells["checkColumn"].Value) == true)
{
UpTpOne = UpTpOne + 1;
if (UpTpOne == 1)
{
flag = true;
}
else
{
flag = false;
}
}
}
if (flag == true)
{
Btn_Edit.Visible = true;
}
else
{
Btn_Edit.Visible = false;
}
}
}
In this step when i run the program and click on checkboxes for first Btn_Edit dont go to true and for secound click Btn_Edit.Visiable go to true.
I want checkedchange event or an event that when i click on checkbox go to event codes in that moment.
(Sorry for bad English)
I proved it myself and had to do this to work:
private void GrdVw_Reception_CellClick(object sender, DataGridViewCellEventArgs e)
{
if(e.ColumnIndex == TheColumnIndexOfTheCheckBoxColumn){
bool currentValue = !(bool)GrdVw_Reception.Rows[e.RowIndex].Cells[0].Value;
GrdVw_Reception.Rows[e.RowIndex].Cells[0].Value = currentValue;
GrdVw_Reception.EndEdit();
MessageBox.Show("Value " + currentValue.ToString());
}
}
When the even click happens the value haven't change, so, i changed it myself and call EndEdit() method of the dataGridView. It works that way.
private void GrdVw_Reception_CellContentClick_1(object sender, DataGridViewCellEventArgs e)
{
if (GrdVw_Reception.CurrentCellAddress.X == 0)
{
if (Convert.ToBoolean(GrdVw_Reception.Rows[e.RowIndex].Cells[0].Value) == false)
{
GrdVw_Reception.Rows[e.RowIndex].Cells[0].Value = CheckState.Checked;
}
else
{
GrdVw_Reception.Rows[e.RowIndex].Cells[0].Value = CheckState.Unchecked;
}
int UpTpOne = 0;
bool flag = false;
for (int i = 0; i < GrdVw_Reception.Rows.Count; i++)
{
if (Convert.ToBoolean(GrdVw_Reception.Rows[i].Cells["checkColumn"].Value) == true)
{
UpTpOne++;
if (UpTpOne == 1)
{
flag = true;
}
else
{
flag = false;
}
}
}
if (UpTpOne == 0)
{
Btn_DelRecord.Visible = false;
}
else
{
Btn_DelRecord.Visible = true;
}
if (flag == true)
{
Btn_Edit.Visible = true;
}
else
{
Btn_Edit.Visible = false;
}
}
}
In this code i made value of checkbox to true by code and then counting number of checkboxescell that has been checked.
I wanted make visiable of Btn_Edit go to false if the checked boxes number is up to one and.....
You should make checkbox tick to ticked and value of cell to true by code because when you click on gridviewcellcheckbox for first, the row go to selecting and in secound click the value going to be true.
I googled a lot but can't reach any good answer and this code is a total of my thinking if you have any good idea for do it better please call me.
Related
I have a WPF triggered (TextChanged) function which calls two other function whose subroutine deletes rows from a DataGrid object when certain conditions are met.
I have a feeling I might be encountering race conditions on the delete of multiple rows. When I place a MessageBox.Show("somethings'); in between the two functions, 2 rows from DataGrid are deleted as expected with the message box popping up in between delete actions.
deleteFunction("item1");
MessageBox.Show("something");
deleteFunction("item2");
However if I remove the MessageBox only the first function deletes a single row (item1)from DataGrid.
deleteFunction("item1");
deleteFunction("item2");
I have tried all sorts of ways to resolve this, Thread.Sleep(500) in between function calls, setting up a Queue to FIFO the requests, thread locking. async ... Nothing seems to work for me.
I'm not even sure it is actually a race condition issue anymore. I am starting to wonder if there is some Thread connection to the DataGrid object that the MessageBox is severing when invoked and releasing the control for another function to interact with.
Code below:
private void streamCode_TextChanged(object sender, TextChangedEventArgs e)
{
if (configurationSectionLoaded == true)
{
streamCodeAlphanumeric(streamCode.Text);
streamCodeIsChar128(streamCode.Text);
}
formEdited = true;
}
private bool streamCodeAlphanumeric(string value)
{
dataValidation dv = new dataValidation();
if (dv.isAlphanumeric(value))
{
streamCode.Background = Brushes.LightGreen;
editStreamcode.Background = Brushes.LightGreen;
editStreamcode.IsEnabled = true;
//MessageBox.Show("scE01 Deleting");
//q.Enqueue(new UILogDeleteQueue() { qEntryType = "scE01" });
try
{
UILogRemoveRow("scE01");
}
catch(Exception e)
{
MessageBox.Show(e.ToString());
}
return true;
}
else
{
editStreamcode.IsEnabled = false;
streamCode.Background = Brushes.LightPink;
UILogAddRow("scE01", "Stream Code", "Non-Alphanumeric Characters Detected!");
return false;
}
}
private bool streamCodeIsChar128(string value)
{
dataValidation dva = new dataValidation();
if (dva.isChar128(value))
{
streamCode.Background = Brushes.LightGreen;
editStreamcode.Background = Brushes.LightGreen;
editStreamcode.IsEnabled = true;
//MessageBox.Show("scE02 Deleting");
try
{
UILogRemoveRow("scE02");
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
return true;
}
else
{
editStreamcode.IsEnabled = false;
streamCode.Background = Brushes.LightPink;
UILogAddRow("scE02", "Stream Code", "Invalid Length Detected!");
return false;
}
}
Finally here is the delete row code:
private void UILogRemoveRow(string entryCode)
{
int rowCount;
rowCount = UILog.Items.Count;
if (rowCount > 0)
{
for (int i = 0; i < rowCount; i++)
{
DataGridRow row = (DataGridRow)UILog.ItemContainerGenerator.ContainerFromIndex(i);
var selectedItem = UILog.ItemContainerGenerator.ContainerFromIndex(i);
if (row != null)
{
UILogObject theItem = (UILogObject)row.DataContext;
if (theItem.entryType == entryCode)
{
UILog.Items.RemoveAt(i);
}
}
}
}
}
Any assistance would be greatly appreciated.
UPDATE: included UILogAddRow function
private void UILogAddRow(string entryCode, string entryIdentifier, string entryDetail)
{
bool itemExists = false;
int rowCount;
rowCount = UILog.Items.Count;
if (rowCount > 0)
{
for (int i = 0; i < rowCount; i++)
{
DataGridRow row = (DataGridRow)UILog.ItemContainerGenerator.ContainerFromIndex(i);
if (row != null)
{
UILogObject theItem = (UILogObject)row.DataContext;
if (theItem.entryType == entryCode)
{
itemExists = true;
}
}
}
}
else
{
//MessageBox.Show(rowCount.ToString());
}
if (itemExists != true)
{
UILog.Items.Add(new UILogObject() { entryType = entryCode, identifier = entryIdentifier, detail = entryDetail });
}
UILog.Items.Refresh();
}
instead of working with low-level container elements (DataGridRow), cast items to your known type, and then search and remove
private void UILogRemoveRow(string entryCode)
{
var item = UILog.Items.OfType<UILogObject>()
.FirstOrDefault(x => x.entryType == entryCode);
if (item != null)
UILog.Items.Remove(item);
}
In C#, I cannot get DataGridViewCheckBoxColumn event to work. It always get a FALSE value even though I’ve clicked on the checkbox. The other datagridviews (text and combobox) columns work fine. Here is what I am doing…
OK, so I am dynamically creating datagridviews (DGVs) at runtime in my constructor based on how many tab sheets there are in the tab control which is determined by the number of weeks in any given date range i.e. one DGV per tab page (where you tab page for each week)
for (int i = 0; i < wcNumWeeks; i++)
{
foreach (DataRow dr in wbDatesDT.Rows)
{
if (Convert.ToInt16(dr["tabNo"].ToString()) == i + 1)
{
wcDate = Convert.ToDateTime(dr["wcDate"].ToString());
break;
}
}
weeksTabControl.TabPages.Add(wcDate.ToShortDateString());
weeksTabControl.TabPages[i].AutoScroll = true;
weeksTabControl.TabPages[i].Width = 1500;
weeksTabControl.TabPages[i].Height = 700;
weeksTabControl.TabPages[i].Controls.Add(new DataGridView()
{
Name = "dataGridView" + (i + 1).ToString(),
Dock = DockStyle.Fill,
Width = 1450,
Height = 650,
Anchor = (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right),
ScrollBars = System.Windows.Forms.ScrollBars.Both,
AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
});
}
Again in the constructor, for each datagridview created I am creating event as follows:
foreach (Control thisControl in weeksTabControl.Controls)
{
if (thisControl.GetType() == typeof(TabPage))
{
foreach (Control dgv in thisControl.Controls)
{
if (dgv.GetType() == typeof(DataGridView))
{
BuildWhiteboardDGV((DataGridView)dgv);
PopulateWhiteboardDGV((DataGridView)dgv);
wbDataGridView = (DataGridView)dgv;
wbDataGridView.CellMouseUp += new DataGridViewCellMouseEventHandler(wbDataGridView_CellMouseUp);
wbDataGridView.CellEndEdit += new DataGridViewCellEventHandler(wbDataGridView_CellEndEdit);
wbDataGridView.CurrentCellDirtyStateChanged += new EventHandler(wbDataGridView_CurrentCellDirtyStateChanged);
wbDataGridView.CellValueChanged += new DataGridViewCellEventHandler(wbDataGridView_CellValueChanged);
}
}
}
}
The events themselves are as follows:
void wbDataGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (wbDataGridView.IsCurrentCellDirty)
{
wbDataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
void wbDataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
try
{
if (e.ColumnIndex >= 13 && e.ColumnIndex <= 15)
{
System.Drawing.Point cur = new System.Drawing.Point(e.ColumnIndex, e.RowIndex);
DataGridViewCheckBoxCell curCell = (DataGridViewCheckBoxCell)wbDataGridView[cur.X, cur.Y];
if (curCell.Value != null && (bool)(curCell.Value) == true)
{
MessageBox.Show("TRUE");
}
else if (curCell.Value != null && (bool)(curCell.Value) == false)
{
MessageBox.Show("FALSE");
}
else
{
MessageBox.Show("NULL");
}
}
return;
}
catch (Exception ex )
{
MessageBox.Show("wbDataGridView_CellValueChanged() ERROR - " + ex.Message + " --> " + ex.InnerException.ToString());
return;
}
}
Where am I going wrong?
OK.... I think I've sorted it.
In my CellMouseUp() event, I had not catered for the LEFT button.
Therefore, by now adding that, the CellValueChanged() event works correctly and captures the correct DataGridViewCheckCellColumn check state : TRUE when checked and FALSE when unchecked.
public void wbDataGridView_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left && e.RowIndex != -1) // added this and it now works
{
this.rowIndex = e.RowIndex;
this.colIndex = e.ColumnIndex;
this.wbDataGridView = (DataGridView)sender;
return;
}
if (e.Button == System.Windows.Forms.MouseButtons.Right && e.RowIndex != -1)
{
this.rowIndex = e.RowIndex;
this.colIndex = e.ColumnIndex;
this.wbDataGridView = (DataGridView)sender;
return;
}
}
Thanks for your comments though. Much appreciated.
Jobs a good un !!!!
I have a Datagridview within a windows form which loads data. I have also included a checkbox column to this Datagridview in run time. My question is how can i know if any of the checkboxs from the checkbox column has been checked, and if a checkbox has been checked enable a button. I have used CellValueChanged event to perform above task but unable to get the desired result.
This is what i have done
List<int> ChkedRow = new List<int>();
for (int i = 0; i <= Datagridview1.RowCount - 1; i++)
{
if (Convert.ToBoolean(Datagridview1.Rows[i].Cells["chkcol"].Value) == true)
{
button1.Enabled = true;
}
else
{
button1.Enabled = false;
}
}
set false before the loop
button1.Enabled = false;
when you found checked item, set it as Enabled true and break the loop
button1.Enabled = true;
break;
code:
button1.Enabled = false;
for (int i = 0; i <= Datagridview1.RowCount - 1; i++)
{
if (Convert.ToBoolean(Datagridview1.Rows[i].Cells["chkcol"].Value))
{
button1.Enabled = true;
break;
}
}
Or you can do below as well
button1.Enabled = false;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
DataGridViewCheckBoxCell cell = row.Cells[colCheckIndex] as DataGridViewCheckBoxCell;
if (cell.Value == cell.TrueValue){
button1.Enabled = true;
break;
}
}
Try this code
button1.Enabled = false;
foreach (DataGridViewRow row in Datagridview1.Rows)
{
if (((DataGridViewCheckBoxCell)row.Cells["chkcol"]).Value)
{
button1.Enabled = true;
break;
}
}
or
//This will always call the checking of checkbox whenever you ticked the checkbox in the datagrid
private void DataGridView1_CellValueChanged(
object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == [Your column index])
CheckForCheckedValue();
}
private void CheckForCheckedValue()
{
button1.Enabled = false;
foreach (DataGridViewRow row in Datagridview1.Rows)
{
if (((DataGridViewCheckBoxCell)row.Cells["chkcol"]).Value)
{
button1.Enabled = true;
break;
}
}
}
NOTE
Don't forget to check the for Null value and do something if it is NULL
What should I add to my code to only show the results of my search?
Right now when I search the searchresult becomes selected (highlighted) and the others remain the same.
Been trying to hide the other rows but without any success (and only show the searchresult, alone). Any suggestions?
Im using a datagridview.
My code:
private void button3_Click_1(object sender, EventArgs e)
{
string search = textBox1.Text;
for (int i = 0; i < dgTest.Rows.Count; i++)
{
if (dgTest.Rows[i].Cells[0].Value.ToString() == search)
{
dgTest.Rows[i].Selected = true;
break;
}
else
{
dgTest.Rows[i].Selected = false;
}
}
}
If your DataGridView is not bound to a data source, then setting the row's Visible property to false will hide it:
for (int i = 0; i < dgTest.Rows.Count; i++)
{
var row = dgTest.Rows[i];
if (row.Cells[0].Value.ToString() == search)
{
row.Selected = true;
row.Visible = true;
}
else
{
row.Selected = false;
row.Visible = false;
}
}
(I removed the 'break' command, as even after you have found the matching row, you would want to continue and hide the other rows.)
If you're using DataBinding, though, it's not so easy, as shown in this page.
you can try this:
for (int i = 0; i < dgTest.Rows.Count; i++)
{
if (dgTest.Rows[i].Cells[0].Value.ToString() == "search")
{
dgTest.Rows[i].Selected = true;
dgTest.Rows[i].Visible = true;
}
else
{
dgTest.Rows[i].Visible = false;
dgTest.Rows[i].Selected = false;
}
}
I'm trying to understand what's happening here. I have a CheckedListBox which contains some ticked and some un-ticked items. I'm trying to find a way of determining the delta in the selection of controls. I've tried some cumbersome like this - but only works part of the time, I'm sure there's a more elegant solution. A maybe related problem is the myCheckBox_ItemCheck event fires on form load - before I have a chance to perform an ItemCheck. Here's what I have so far:
void clbProgs_ItemCheck(object sender, ItemCheckEventArgs e)
{
// i know its awful
System.Windows.Forms.CheckedListBox cb = (System.Windows.Forms.CheckedListBox)sender;
string sCurrent = e.CurrentValue.ToString();
int sIndex = e.Index;
AbstractLink lk = (AbstractLink)cb.Items[sIndex];
List<ILink> _links = clbProgs.DataSource as List<ILink>;
foreach (AbstractLink lkCurrent in _links)
{
if (!lkCurrent.IsActive)
{
if (!_groupValues.ContainsKey(lkCurrent.Linkid))
{
_groupValues.Add(lkCurrent.Linkid, lkCurrent);
}
}
}
if (_groupValues.ContainsKey(lk.Linkid))
{
AbstractLink lkDirty = (AbstractLink)lk.Clone();
CheckState newValue = (CheckState)e.NewValue;
if (newValue == CheckState.Checked)
{
lkDirty.IsActive = true;
}
else if (newValue == CheckState.Unchecked)
{
lkDirty.IsActive = false;
}
if (_dirtyGroups.ContainsKey(lk.Linkid))
{
_dirtyGroups[lk.Linkid] = lkDirty;
}
else
{
CheckState oldValue = (CheckState)e.NewValue;
if (oldValue == CheckState.Checked)
{
lkDirty.IsActive = true;
}
else if (oldValue == CheckState.Unchecked)
{
lkDirty.IsActive = false;
}
_dirtyGroups.Add(lk.Linkid, lk);
}
}
else
{
if (!lk.IsActive)
{
_dirtyGroups.Add(lk.Linkid, lk);
}
else
{
_groupValues.Add(lk.Linkid, lk);
}
}
}
Then onclick of a save button - I check whats changed before sending to database:
private void btSave_Click(object sender, EventArgs e)
{
List<AbstractLink> originalList = new List<AbstractLink>(_groupValues.Values);
List<AbstractLink> changedList = new List<AbstractLink>(_dirtyGroups.Values);
IEnumerable<AbstractLink> dupes = originalList.ToArray<AbstractLink>().Intersect(changedList.ToArray<AbstractLink>());
foreach (ILink t in dupes)
{
MessageBox.Show("Changed");
}
if (dupes.Count() == 0)
{
MessageBox.Show("No Change");
}
}
For further info. The definition of type AbstractLink uses:
public bool Equals(ILink other)
{
if (Object.ReferenceEquals(other, null)) return false;
if (Object.ReferenceEquals(this, other)) return true;
return IsActive.Equals(other.IsActive) && Linkid.Equals(other.Linkid);
}
There's little point that I see to do this in the ItemCheck event. Just calculate the delta when you save. Cuts out a bunch of code and trouble with spurious events.