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.
Related
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;
}
}
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 ))
{
....
}
This have been developed by using some third party component such as C1. As you can see there are are three kinds of rows here...
Type 1. L0000000000000000420 - this kind of row is fetched from database. (Read Only)
Type 2. Enter Amount - this kind of row is for the user to input amount. (this one might also contain drop downlist in some columns) (Editable only when Checked)
Type 3. WHITE ROW- this is just a blank Read Only row for better look and feel.
I want to know is it possible to create similar if not exactly the same kind of DataGridView without using any third party component?
My idea is .. to fetch the rows from database into a DataTable and then loop it ... I am thinking of adding two extra blank rows in the DataTable after each row that has been fetched.
I will also add a column which will have a value such as ,
A - (this is to indicate type 1)
B - (this is to indicate type 2)
C - (this is to indicate type 3)
A
B
C .. so on
I will then check the type of row in a loop and then set property of that row to read only/ editable , color properties accordingly.
But I am not sure if this is practically possible. I am not not sure how am i gonna add ComboBox for only tpe 2 column. Because if I add a ComboBox column it will be displayed in all three rows. Is this possible? If yes, can you give me some idea how? I need to know how I can do this before I ask some more specific questions. Thank You.
I may agree that WPF is better/faster for these kind of things, but it's his choice whether to use it or not. And learning WPF from scratch is NOT that fast...
As long as manually bind your data to your DataGridView you can control the behavior and look of your single cells, including of course the color (that's the easiest part). I include an example for the "disappearing combobox" cell. The last column is a simple DataGridViewComboBoxColumn.
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.Rows.Add(new[] { "L00000422", "", "","A" });
dataGridView1.Rows.Add(new[] { "Enter Amount", "", "","" });
dataGridView1.Rows.Add(new[] { "", "", "","" });
dataGridView1.Rows.Add(new[] { "L00000423", "", "" ,"B"});
dataGridView1.Rows.Add(new[] { "Enter Amount", "", "", "" });
dataGridView1.Rows.Add(new[] { "", "", "", "" });
foreach (var row in dataGridView1.Rows)
{
var r = (DataGridViewRow) row;
foreach (var col in dataGridView1.Columns)
{
var cl = (DataGridViewColumn) col;
if (cl.Index == 3)
{
var cc = (DataGridViewComboBoxCell)dataGridView1[3,r.Index];
if (r.Index % 3 != 0)
{
cc.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing;
cc.ReadOnly = true;
}
else
{
cc.DisplayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton;
cc.ReadOnly = false;
}
}
}
}
}
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.
I am working with a gridview that pulls data from a SQL database based on selections in dropdown lists. The source table has six columns for attributes of the selection, but depending on what is chosen, there could be anywhere from one to six of those that are empty (all null values). When the column is empty, I would like to have it hidden so the page is less clunky and confusing.
I've searched around for an answer for the past couple days, but what I have found so far is either related to hiding columns that you know are empty which I will not know or removing them in the SQL code which I think doesn't work if the column is called for in the gridview code and doesn't exist in the query.
I'm very new to ASP.NET, so I'm sorry if some of my terminology is off! Let me know if you have any questions about what I'm asking.
Thanks in advance for your help!
Instead of hiding empty columns, why don't you add the columns you want in code behind?
When you retrieve the data to be displayed, you know which columns are present. You can add them and databind them in code behind.
To get you started with this, here is some code from a helpful article on how to do this:
BoundField nameColumn = new BoundField();
nameColumn.DataField = "Name";
nameColumn.HeaderText = "Person Name";
GridView1.Columns.Add(nameColumn);
You could try:
Set up the gridview will all columns hidden (Visible="false")
In the gridview's RowDataBound event, check each of the column values and if it has data, set the column to show (Visible="true")
The RowDataBound method could look something like this:
void YourGridview_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// if this is a SqlDataSource you can use DataRowView,
// otherwise use whatever type is used in the data source
DataRowView rowView = (DataRowView)e.Row.DataItem;
if (!String.IsNullOrEmpty(rowView["ColumnA"]))
YourGridview.Columns[0].Visible = true;
// repeat for your other columns
}
}
Best way to do that for web:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;
namespace MyProject
{
public static class ExtensionGridView
{
public static GridView RemoveEmptyColumns(this GridView gv)
{
// Make sure there are at least header row
if (gv.HeaderRow != null)
{
int columnIndex = 0;
// For each column
foreach (DataControlFieldCell clm in gv.HeaderRow.Cells)
{
bool notAvailable = true;
// For each row
foreach (GridViewRow row in gv.Rows)
{
string columnData = row.Cells[columnIndex].Text;
if (!(string.IsNullOrEmpty(columnData) || columnData ==" "))
{
notAvailable = false;
break;
}
}
if (notAvailable)
{
// Hide the target header cell
gv.HeaderRow.Cells[columnIndex].Visible = false;
// Hide the target cell of each row
foreach (GridViewRow row in gv.Rows)
row.Cells[columnIndex].Visible = false;
}
columnIndex++;
}
}
return gv;
}
}
}
Instead of this code:
if (!String.IsNullOrEmpty(rowView["ColumnA"]))
YourGridview.Columns[0].Visible = true;
Use this one:
if (!String.IsNullOrEmpty(Convert.Tostring(rowView["ColumnA"])) )
YourGridview.Columns[0].Visible = true;
on the onItemBound event of the grid, you can check the value of the variable to be set in the column cell and set its visibility accordingly