Get Dropdown item value while reading Excel file - C# - c#

I'm reading an Excel spreadsheet using the microsoft.office.interop.excel library in C#.
I need to first determine that a cell in the sheet contains a Dropdown and then read the value of the Dropdown.
I'm running through the rows of the sheet and parsing values, but it's possible that a cell contains a Dropdown with a selection instead of a text value and I'm having problems trying to get the Dropdown from a cell in order to read it's selected value.
The pseudo code below is an example of what I'm trying:
for(int row = 1; row <= rowCount; row++)
{
for(int col = 1; col <= colCount; col++)
{
//Have the row and column number of the individual cell here
Range range = worksheet.Cells.Item[row,col]; //Get the thing in the cell?
Type type = range.GetType(); //Try to get a type so I can compare it against a Dropdown?
string menuVal = range.Value(); //Both this and range.Value2() is null
}
}
What I'd like to do is something like this fantasy code:
for( -row loop- )
{
for( -col loop- )
{
if (Current Cell contains a Dropdown)
{
Dropdown menu = Get the Dropdown in this cell;
string value = Get the 'Dropdown' value;
}
}
}
Can someone please help me out here? I haven't been able to find any documentation on how to GET the value - plenty on how to create the Dropdown itself though.
Edit: Changed 'Menu' to 'Dropdown'. Dropdown is the actual class that's being used in the code.
Solution in a nutshell: The Dropdown class from microsoft.office.interop should -NOT- be used if you care about trying to actually retrieve the value of the dropdown programmatically. This has been either deprecated or is just something Microsoft doesn't want you using.
Instead you should use the method that sets up the Dropdown validation by using a separate worksheet that contains the values for the dropdown menu. You can then read the Value of the Dropdown cell as though it's just text.

Related

DisplayIndex reading incorrectly when rows hidden

The goal is to copy the selected cell data out of a selected row.
I'm doing this by catching the CopyingRowClipBoardContent event inside my datagrid and redirecting it to this code:
var currentCell = e.ClipboardRowContent[VwrGrid.CurrentCell.Column.DisplayIndex];
e.ClipboardRowContent.Clear();
e.ClipboardRowContent.Add(currentCell);
This works perfectly! the only issue, is that if some of the columns are hidden, DisplayIndex reads improperly.
So if we have Item 1, Item 2, and Item 3.
If all are showing and I selected item3 and copy it, I get the cell value in Item 3.
The problem is, If Item 2 is collapsed/not shown, then copying Item 3 will tell you you're trying to copy out of bounds. because it's counted displayIndex , 3 from the left, and only two were shown. so it's moved outside of the table
For WPF Datagrid, try this:
// The clipboard row works only for visible cells
// To obtain the data column use the columnIndex and then map that to the Columns collection
int columnIndex = dataGrid.CurrentCell.Column.DisplayIndex;
var column = dataGrid.Columns[columnIndex];
// Now get the needed column
var cellContent = e.ClipboardRowContent.Where(i => i.Column == column).First();
e.ClipboardRowContent.Clear();
e.ClipboardRowContent.Add(cellContent);
For Winforms:
Use .Index instead. .DisplayIndex applies only to visible columns.
Because this is WPF and I can't simply use an index, I just iterated through the columns and counter the number of columns that had their visibility set to collapsed up to the column we were attempting to grab the displayindex for. Then subtracted that number from the displayIndex.
private void DataGrid_CopyingRowClipboardContent(object sender, DataGridRowClipboardEventArgs e)
{
//because we need to use displayindex, we need to check how many collapsed columns there are before our column, and adjust our display index accordingly
int invisibleCols = 0;
foreach(DataGridColumn col in VwrGrid.Columns)
{
if (col.Visibility == Visibility.Collapsed)
invisibleCols++;
if (col.Header.ToString() == VwrGrid.CurrentCell.Column.Header.ToString()) break;
}
try
{
var currentCell = e.ClipboardRowContent[VwrGrid.CurrentCell.Column.DisplayIndex - invisibleCols];
e.ClipboardRowContent.Clear();
e.ClipboardRowContent.Add(currentCell);
}
catch
{
}
}

How to select a row in gridview by code based on its key value?

I'm using asp.net web forms application to view data of certain table in grid view & select a row in this grid view based on ID of this data row (Key Value) retrieved from query string
I tried using this code in Code behind
gridview1.SelectedValue= Request.QueryString["RowToSelectID"];
but it said that selected value is a read only property and can't be assigned
Is there another way to do that ?
Try the following and see here for more information.
var keyValue = 1; // Replace with your Convert.ToInt32(Request.QueryString["RowToSelectID"])
for (int i = 0; i <= this.gridview1.DataKeys.Count - 1; i++)
{
if ((int)gridview1.DataKeys[i].Value == keyValue )
{
this.gridview1.SelectedIndex = i;
}
}
I used the SelectedIndex. The record in the GridView having a key value of 1, will be selected.

Searching DataGrid for matching values

I Have a data grid which can be queried based on a comboBox choice .
My code (shown below) is meant to search through the datagrid and if it finds a row with a matching piece of text it is meant to move the datagrids selected index to the corresponding row.
for (int i = 0; i <= DashBoard_DataGrid.Columns.Count - 1; i++)
{
if (DashBoard_DataGrid.Rows[0].ToString().ToLower().Contains(comboBox9.Text.ToString().ToLower()))
{
value = dr.Cells[i].Value.ToString();
// return dr.Cells[i].RowIndex;
DashBoard_DataGrid.SelectedCells[i].RowIndex = dr.Cells[i].RowIndex;
}
}
However I am getting the following error
Error 7 Property or indexer 'System.Windows.Forms.DataGridViewCell.RowIndex' cannot be assigned to -- it is read only
Does anyone know how to fix this error ? searching online hasn't givin a solution
You are trying to change a SelectedCell's row index, which is read-only. If you are trying to change the selected row, you need to set the SelectedIndex for the DataGrid.
DashBoard_DataGrid.SelectedIndex = dr.Cells[i].RowIndex;
Also, try changing SelectedCells to SelectedRows.
try this
.
DashBoard_DataGrid.ClearSelection();
DashBoard_DataGrid.Rows[3].Selected = true;
or if you want to select a specific cell, then
DashBoard_DataGrid.ClearSelection();
DashBoard_DataGrid[0, i].Selected = true;
this will select the first column of the desired row..

converting cells into text boxes where check box is checked

I am using mysql and asp.net with c#. I have a grid view which will display dynamically selected table data. I am able to display the data of selected table. In the first column i have added a check box and a Button outside Grid view. When user selects Check box and clicks on button, the selected rows must turn into text boxes. I am able to find the seleted check box, but i'm unable to convert the cells into text boxes. Here's my code:
int n = GridView1.HeaderRow.Cells.Count;
for( int i=0; i < GridView1.Rows.Count;i++)
{
GridViewRow row = GridView1.Rows[i];
bool isChecked = ((CheckBox)row.FindControl("CheckBox1")).Checked;
{
for( int j=0;j<n;j++)
{
TextBox txt = ((TextBox)GridView1.Rows[i].Cells[j]).Text;
}
}
}
At this line: TextBox txt = ((TextBox)GridView1.Rows[i].Cells[j]).Text;
i get a warning :
cannot convert 'System.Web.UI.Controls.TableCell' to type 'System.Web.UI.Controls.TextBox
I am unable to resolve this. Please help. Thank you
Try this.
You can remove one or few lines based on your hands-on with C#.
Concept is, you should create a TextBox, assign cell text that textbox and then Add that newly created textbox to child controls of Grid Cell of particular row.
Mark this solution if you found useful.
bool isChecked = ((CheckBox)row.FindControl("CheckBox1")).Checked;
if(isChecked)
{
for( int j=0;j<n;j++)
{
TextBox tbForCell = new TextBox();
tbForCell.Text = GridView1.Rows[i].Cells[j].Text;
GridView1.Rows[i].Cells[j].Text = "";
GridView1.Rows[i].Cells[j].Controls.Add(tbForCell);
}
}
If you want to avoid the TextBox to appear in CheckBox Column please initialise loop variable j with 1 instead of 0.
for( int j=1;j<n;j++)
Your method call is finding the cell. The Textbox is a control contained within the cell. Try something like this instead:
TextBox txt = ((TextBox) GridView1.Rows[i].Cells[j].FindControl("textbox name")).Text;
The FindControl method is documented here.
Also take #Bartdude's advice about using editable gridviews. If one will work at least as well as what you're trying to hand-roll, it's worth the time learning how to use it.

How to read column names of a multicolumn ListView control?

What is the best way to find the names of the columns of a ListView?
I converted a DataTable to a List using a procedure I found on this forum, but I cannot make it to put the Id column first, especially because not all of my DataTables have a column "Id".
I can search in collection listView.Columns.ToString() but the format I am seeing is:
"ColumnHeader: Text: Id"
which I have to parse to find the proper name "Id".
This does not look like the spirit of C#.
I also tried: listView.SelectedItems[0].SubItems["Id"]
but that does not compile.
Ok Here is the complete code.
The exact problem is that the user selects a row in the listView with Courier Names and Ids, but it could also be Ids and Names, in that order. The fastest way to find the Id of the selected courier would be:
ListViewItem si = listCouriers.SelectedItems[0];
CourierId = si.SubItems["Id"].Text;
but that does not work. The hardcoded way would be this, but I cannot guarantee that some day the wrong column will be used:
ListViewItem si = listCouriers.SelectedItems[0];
CourierId = si.SubItems[1].Text;
Using #HuorSwords method leads to this not-so-simple solution, which works for me, but depends on the reasonable assumption that the order of columns in the ColumnHeaderCollection corresponds to the display on the form:
ListViewItem si = listCouriers.SelectedItems[0];
string CourierId = null;
int icol = 0;
foreach (ColumnHeader header in listCouriers.Columns)
{
if (header.Text == "Id")
{
CourierId = si.SubItems[icol].Text;
break;
}
icol++;
}
As listView.Columns is of type ListView.ColumnHeaderCollection, then it contains ColumnHeader objects.
The ColumnHeader.Text contains the column title, so you can check for concrete column with:
foreach (ColumnHeader header in listView.Columns)
{
if (header.Text == "Id")
{
// Do something...
}
}
I don't know if is the best approach, but you don't need to parse the results to find "Id" value...
UPDATE
Also, have you tried to reference it with the String indexer? > listView.Columns["Id"]
use this code:
private ColumnHeader GetColumn(string Text)
{
for (int i = 0; i < listView1.Columns.Count; i++)
for (int j = 0; j < listView1.Items.Count; j++)
if (listView1.Items[j].SubItems.Count - 1 >= i)
if (listView1.Items[j].SubItems[i].Text == Text)
return listView1.Columns[i];
return null;
}
just give item text to this code and get everything you want of a column.
Enjoy ;)

Categories