FocusedRowHandle not setting correctly in a DevExpress GridView C# - c#

I am trying to update my GridView to auto select a new row that is added after the user fills out the fields and presses add. However, I am having no luck when trying to set the FocusedRowHandle property. The FocusedRowHandle value stays at -2147483648 even after I try to assign a value to it as shown in the following code:
private void gvExample_RowUpdated(object sender, RowObjectEventArgs e)
{
try
{
ExampleMethodToUpdateTableAdapter();
GridView view = sender as GridView;
Object obj;
if (e.RowHandle != GridControl.NewItemRowHandle)
obj = view.GetRow(view.FocusedRowHandle);
else
{
dsExample.dtExample.DefaultView.Sort = "ID desc";
DataTable dtSorted = dsExample.dtExample.DefaultView.ToTable(true);
int lastID = Convert.ToInt32(dtSorted.Rows[0]["ID"]);
gvExample.FocusedRowHandle = lastID;
}
}
catch (Exception ex)
{
}
}
When stepping into the else statement the aim was to get the latest ID from the DataTable now it has been updated (since the value at e.RowHandle is -2147483648 because its a new row) and set the Focused Row to this ID.
I have tried to have a look online for this but can't seem to find a solution so I thought I'd have a go at posting on here. Apologies if I've missed any info out.

If i understand correct you want to focus the new row (which is the last row):
gridView.FocusedRowHandle = gridView.RowCount - 1;
If not, you have to search the id inside the gridvw with for i 0-> gridView.RowCount - 1 and then when you will find the Id to focus the row with the i value.
for (int i = 0; i <= gridView.RowCount - 1; i++)
{
if (gridView.GetRowCellValue(i, gridView.columns(column_number)))
{
gridView.FocusedRowHandle = i;
}
}

Related

How to determine a row index from a datatable that shares a column with a combobox

I have a combobox and a datatable.
I've added all of the elements of one column in the datatable to the combobox items.
Now whenever the user chooses a item in the combobox, I want to go to the datatable and compare the column, if there's a match, it will do some code.
I have the following
private void comboBox8_SelectedIndexChanged(object sender, EventArgs e)
{
string str = comboBox8.SelectedItem.ToString();
int z = 0;
foreach (var row in datatable.Rows)
{
int i = 0; i++;
if (datatable.Rows[row]["Cidade"] == str)
{
z = i;
}
}
}
"Cidade" is the column name that matches the options in the combobox.
The Problem is that the code doesn't identify the ìf` condition as valid, saying there are invalid arguments
Edit: worked it around like this:
private void comboBox8_SelectedIndexChanged(object sender, EventArgs e)
{
string str = comboBox8.SelectedItem.ToString();
int z = 0;
for (int i = 0; i < DataAccess.Instance.tabelasismica.Rows.Count; i++)
{
if (DataAccess.Instance.tabelasismica.Rows[i]["Cidade"] == str)
{
z = i;
}
}
MessageBox.Show(z.ToString());
MessageBox.Show(DataAccess.Instance.tabelasismica.Rows[z]["Cidade"].ToString());
}
Standard way of doing things like this is to use data-binding. You'd simply set your ComboBox's DataSource to your DataTable. The code would roughly look like this:
comboBox8.DataSource = datatable;
comboBox8.DisplayMember = "Cidade"
comboBox8.ValueMember = "PrimaryKeyColumnOfYourTable"
Now in the SelectedIndexChanged event, you simply use comboBox8.SelectedValue property to get the ID of the selected row. If you have strongly typed DataSet, your DataTable will have a function named FindByYourPKColumn() that you can use to find the row using this ID.
datatable.Rows[row]["Cidade"] is of type object - you need to convert it to a string before comparing it to str, like this:
if (datatable.Rows[row]["Cidade"].ToString() == str)
{ ... }
Try this in place of the for loop
foreach (DataRow row in dDataAccess.Instance.tabelasismica.Rows)
{
if (row["Cidade"].ToString() == str)
{
z = dDataAccess.Instance.tabelasismica.Rows.IndexOf(row);
}
}
or
foreach (DataRow row in dataTable.Rows)
{
if (row["Cidade"].ToString() == str)
{
z = dataTable.Rows.IndexOf(row);;
}
}
Being said that, standard practice in using ComboBoxes, ListBoxes etc with datasources is to to have a distinct column in the data-table assigned as the ValueMember of the ComboBox, which makes life even easier - as suggested by #dotNET.
comboBox8.DataSource= dataTable; //the data table which contains data
comboBox8.ValueMember = "id"; // column name which you want in SelectedValue
comboBox8.DisplayMember = "name"; // column name that you need to display as text
That way you don't have to iterate through the dataTable to find the index of the row, and you can use the ID (ValueMember) to continue process as required.
Example here
#dotNET's answer is the preferred method to solve your specific problem.
However to solve the general problem find a value in a dataset your best bets are to either
Use the ADO.NET methods Find or Select e.g.
var results = dataset.Select(string.Format("Cidade = {0}",str));
if (results.Count() != 0 )
{
...
}
Or use System.Data.DataSetExtensions
if (datatable.AsEnumerable().Any( x=> x.Field<string>("Cidade") == str ))
{
....
}

Property or indexer 'System.Windows.Forms.DataGridViewCell.Visible' cannot be assigned to -- it is read only

I have a datagridview consist of of 5 row something like this:
int number = dataGridView1.Rows.Add();
dataGridView1.Rows[number].Cells[0].Value = result;
dataGridView1.Rows[number].Cells[1].Value = newAddress;
dataGridView1.Rows[number].Cells[2].Value = (string)((Hashtable)ht[1])["value"];
dataGridView1.Rows[number].Cells[3].Value = (string)((Hashtable)ht[2])["value"];
dataGridView1.Rows[number].Cells[4].Value = (string)((Hashtable)ht[3])["value"];
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells[4].Value.ToString() == "")
{
row.Cells[5].Visible = false; //error
}
}
Cell 5 is save button. Now I want to check if the cell number 4 is empty, then set the visibility for cell 5 false(hide button). However, I get this error at the commented line.
Property or indexer 'System.Windows.Forms.DataGridViewCell.Visible' cannot be assigned to -- it is read only
I've checked the datagridview1 and column readonly properties, it is all set to false. But I still face this error.
Can anyone please advice?

Gathering data from datagrid in a specified column and row

In my WPF application I am browsing database in a datagrid. The point of my code is to store selected cells content in datagrid to some list of values for further operations. My code works well for selected items under 12, but for more items it throws an NullRefferenceException that says "
Object reference not set to an instance of an object".
Thank you for help.
code:
List<string> graphValue = new List<string>(dataGrid1.SelectedItems.Count); //create list
IList someList = new ArrayList(dataGrid1.SelectedItems); //define Ilist
DataGridColumn dataGridCol = dataGrid1.Columns[listBox1.SelectedIndex];
//select column whom i wana collect data
if (dataGrid1.SelectedItems != null) //when selection applied..
{
for (int i = 0; i < dataGrid1.SelectedItems.Count; i++) //go row by row in selected column above
{
try
{
id = ((TextBlock)dataGridCol.GetCellContent(someList[i])).Text.ToString(); //save cell content to string
graphValue.Add(id); //add value to Ilist
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Message, "error"); }
}
}
}
This simple code may help you Here first we are going to loop through each record of Data-grid Then select specific cell/column data with loop by Providing Row , and Column as..
for(int row =0; row < dg_CountInventory.Rows.Count; row ++)
{
TextBlock b = dg_CountInventory.Columns[1].GetCellContent(dg_CountInventory.Items[row ]) as TextBlock;
}
When you define your someList with
IList someList = new ArrayList(dataGrid1.SelectedItems);
You actually create an ArrayList with all values are null. After that, you try to archive GetCellContent() method with it.
dataGridCol.GetCellContent(someList[i])).Text
someList[i] is probably null, that's why you get NullRefferenceException. Add some values of this array before use it.
I was googling and I found solution for me. I will give it here for the others. I would appreciate, if someone can explain me what I did wrong in the previous code upper.
This code works for me:
if (dataGrid1.SelectedItems.Count > 0) //when selection applied..
{
for (int i = 0; i < dataGrid1.SelectedItems.Count; i++) //go row by row in selected column above
{
try
{
System.Data.DataRowView selectedFile = (System.Data.DataRowView)dataGrid1.SelectedItems[i];
string str = Convert.ToString(selectedFile.Row.ItemArray[listBox1.SelectedIndex]);
graphValue.Add(str);
}
catch (Exception ex)
{ System.Windows.MessageBox.Show(ex.Message, "error"); }
}
Now I can select in DataGrid more rows than 10.
Refference to: http://www.codeproject.com/Questions/119505/Get-Selected-items-in-a-WPF-datagrid
Now I am really happy, thank you all for your time.

C# foreach statement

I need some help with a for each statement, basically what happens is when a user edits a value within a cell, my foreach will apply this to all cells within the datagrid and change the value of them all, i need my foreach statement to work by iterating through the datagrid but only change the selected row that has been edited
try
{
//loop through each of the rows in the dgv
foreach (DataGridViewRow row in dgvDetials.SelectedRows)
{
int intQtyInsp = 0;
//if quantity inspected is empty:
if (row.Cells[2].Value.ToString() == "")
{
//quantity inspected is 0. Prevents null value errors:
intQtyInsp = 0;
}
intQtyInsp =
Int32.Parse(dgvDetials.CurrentRow.Cells[2].Value.ToString());
if (intQtyInsp < 0) // checks the cell for a negative value
{
intQtyInsp = 0; // if cells is negative submits value as Zero
}
else
{
//sets quantity inspected to value entered
intQtyInsp = Int32.Parse(row.Cells[2].Value.ToString());
}
if (intQtyInsp == 0) //if quantity inspected is 0. Ignore row.
{
}
else //else gather details and insert row as production.
{
area = dtArea2.Rows[0]["area_code"].ToString();
inspDate = dtpInspectionDate.Value.ToString("MM/dd/yyyy");
inspShift = cbShift.Text;
partNo = row.Cells[0].Value.ToString();
// dieCode = row.Cells[0].Value.ToString();
dieCode = "";
machine = "";
qtyInsp = intQtyInsp;
qtyInspRecorded = Int32.Parse(row.Cells[5].Value.ToString());
comment = "";
//machine = row.Cells[3].Value.ToString();
if (qtyInspRecorded == 0)
{
SQLMethods.insertProduction(area,
inspDate,
inspShift,
partNo,
dieCode,
qtyInsp,
comment,
machine);
}
else
{
SQLMethods.updateProduction(area,
inspDate,
inspShift,
partNo,
dieCode,
(qtyInspRecorded + qtyInsp),
comment,
machine);
}
}
}
retrieveData(); //reset values
}
catch (Exception ex)
{
MessageBox.Show(
"Error instering production values. Processed with error: "
+ ex.Message);
}
First of all, I would simplify the code here a little by splitting it into several methods that may be called from the For-loop. That would make it easier to read, and thereby easier to help you too. Just to provide an example, the following:
if (intQtyInsp < 0) // checks the cell for a negative value
{
intQtyInsp = 0; // if cells is negative submits value as Zero
}
else
{
//sets quantity inspected to value entered
intQtyInsp = Int32.Parse(row.Cells[2].Value.ToString());
}
could be replaced with something like:
int intQtyInsp = SetQuantityInspected();
Then that method could contain the if-structure. Repeat this for other parts of the code in the loop too. Trust me, this will make your life easier.
Also, it seems as if the result of this section is never used; the value of intQtyInsp is overwritten right afterwards!:
if (row.Cells[2].Value.ToString() == "")
{
//quantity inspected is 0. Prevents null value errors:
intQtyInsp = 0;
}
As for your question: I'm not sure how you would get the id of the row that is currently being edited. (If possible (?), it might be getter to loop through the table / data source behind the datagrid?).
In any case, what you need to do is something like the following inside your loop:
if(IsCurrentlyEditedRow(row)){
...
// (all the stuff currently in the body of your loop goes here)
...
}
Now you can implement the method IsCurrentlyEditedRow() to return True or False depending on whether or not the id of the current row is the the same as that of the one you are editing.
Sorry if this is not a very specific and detailed answer, hope it is of some use anyway.

Infragistics.Win.UltraWinGrid.DoubleClickCellEvent c#

I was working on a project and I need to read a row in a Infragistics GridList when I clicked twice on the row.This is how I filled my girdlist
try
{
if (txtAd.Text.Replace("'", "").Trim() == string.Empty && txtSoyad.Text.Replace("'", "").Trim() == string.Empty)
{
stBarMsg.Text = "ad soyad girilmeli!";
return;
}
DataTable dt = PrePaidLib.getParaPuanGoruntulemeList(true, txtAd.Text.Replace("'", ""), txtSoyad.Text.Replace("'", ""));
grdList.DataSource = dt;
grdList.DataBind();
}
catch (Exception exp)
{
ErrorLib.ErrorHandle(exp, "frmParaPuanGoruntuleme.retrieveRecord");
}
Here, you can find my double click function
private void grdList_DoubleClickCell(object sender, Infragistics.Win.UltraWinGrid.DoubleClickCellEventArgs e)
{
try
{
txtKartno.Text = grdList.Selected.Columns[0].ToString();//Cells[1].ToString();
}
catch(Exception ex)
{
ErrorLib.ErrorHandle(ex, "grdList_DoubleClickCell");
}
}
This line doesn't work "txtKartno.Text = grdList.Selected.Columns[0].ToString();" By the way I want to get values for each attribute 1 by 1. I have 4 columns in my gridlist. Any suggestions?
When you double click a cell in an Infragistics UltraWinGrid, you receive the cell clicked in the DoubleClickCellEventArgs.Cell property. From this property you can reach the current Row using the e.Cell.Row syntax and from that row you can reach any other cell using the e.Cell.Row.Cells[columnName or columnIndex].Value syntax.
So the data you need could be read in this way
txtKartno.Text = e.Cell.Row.Cells[0].Value.ToString();
(I'm assuming the cell required is not the one clicked and the column is at index zero)
Of course if, the clicked cell is the one you need, the syntax is more concise
txtKartno.Text = e.Cell.Value.ToString();
To complete the answer, please note, the UltraGridRow has two methods that can be used to retrieve a cell value from a row:
string textResult = e.Cell.Row.GetCellText(e.Row.Band.Columns[0]);
object objResult = e.Cell.Row.GetCellValue(e.Row.Band.Columns[1]);
According to Infragistics, these two methods avoid the creation of unneeded cells object and therefore are more performant. In your case, it's not clear if these methods are really beneficial.

Categories