Finding a cell in devexpress datagrid - c#

I'm new to DevExpress GridControl.
I need to find a particular cell in the grid and then do something with it's value.
How do I go about this please?
In the grid's Loaded method, I tried using myGrid.FindRowByValue("ProductType","ABC"), but always gives a negative number.
Thanks.

Here is code you can try
for (int i = 0; i < gridView1.DataRowCount; i++) {
object b = gridView1.GetRowCellValue(i, "FieldName");
if (b != null && b.Equals(<someValue>)){
gridView1.FocusedRowHandle = i;
return;
}
}
you can go to this link for more details.
https://www.devexpress.com/Support/Center/Question/Details/Q132599/get-row-by-cell-value

Unlike XtraGrid, the DXGrid for WPF does not provide the DataRowCount property - that is why we suggested checking the GridControl's ItemsSource. On the other hand, our grid has the VisibleRowCount property, which will be useful in some scenarios.
To accomplish this task, iterate through visible grid rows manually as shown below.
void MoveFocusToLast(GridControl grid, string fieldName, object value) {
for (int i = grid.VisibleRowCount - 1; i >= 0; i--) {
var handle = grid.GetRowHandleByVisibleIndex(i);
var currentValue = grid.GetCellValue(handle, fieldName);
if (currentValue != null && currentValue.Equals(value)) {
grid.View.FocusedRowHandle = handle;
return;
}
}
}
Grid also provides the FindRowByValue method, which allows you to
find a row by a specific cell value. This method returns the handle of
the corresponding row, and you can make that row visible by setting
the FocusedRowHandle property or calling ScrollIntoView. I
have prepared a sample demonstrating this approach.
See Also:
Traversing Rows
Find Row
Get RowHandle from a cell value

Related

Read each cell values in WPF gridview

I have a datagridview in wpf called datagrid1. I need to read value in each cells in datagrid. I know how to do it in windows form
string result = datagrid1.Rows[0].Cells[1].Value.ToString();
How do this in WPF?
There is no easy way to do this in WPF, however this tutorial can be of use to you.
Edit:
First of all I totally agree with the comment Nitin Joshi mentioned above.
Second, According to this answer The WPF datagrid was built to bind to something like a DataTable. The majority of the time, you will modify the DataTable, and the Rows/Columns within the DataTable that is bound to the DataGrid, not the DataGrid it self so you don't need to use something like this datagrid1.Rows[0].Cells[1].Value. But if you still insist on getting the value that way, here is a solution :
Second EDIT:
Since you asked only for a way to read call value, I'll make my answer shorter but also a little more concrete:
GetCellValue method returns a string value representing cell content of a given DataGrid by column/row indices:
I wrote this method assuming column types are either TextBox, TextBlock or ComboBox. Other Types could be handled the same way.
public string GetCellValue(DataGrid datagrid, int row, int column)
{
var cellInfo = new DataGridCellInfo(
datagrid.Items[row], dataGrid.Columns[column]);
DataGridCell cell = null;
var cellContent = cellInfo.Column.GetCellContent(cellInfo.Item);
if (cellContent != null)
cell = (DataGridCell)cellContent.Parent;
if (cell == null) return string.Empty;
// if DataGridTextColumn / DataGridComboBoxColumn is used
// or AutoGeneratedColumns is True
if (cell.Content is TextBlock)
return ((TextBlock)cell.Content).Text;
else if (cell.Content is ComboBox)
return ((ComboBox)cell.Content).Text;
// if DataGridTemplateColumn is used
// assuming cells are either TextBox, TextBlock or ComboBox. Other Types could be handled the same way.
else
{
var txtPresenter = FindVisualChild<TextBox>((ContentPresenter)cell.Content);
if (txtPresenter != null) return txtPresenter.Text;
var txbPresenter = FindVisualChild<TextBlock>((ContentPresenter)cell.Content);
if (txbPresenter != null) return txbPresenter.Text;
var cmbPresenter = FindVisualChild<ComboBox>((ContentPresenter)cell.Content);
if (cmbPresenter != null) return cmbPresenter.Text;
}
return string.Empty;
}
public static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is T)
return (T)child;
else
{
T childOfChild = FindVisualChild<T>(child);
if (childOfChild != null)
return childOfChild;
}
}
return null;
}
Then calling string result = GetCellValue(dataGrid, 2, 1); (e.g. from a Button click event), will return the value of dataGrid[2,1].
*Note:
The SelectionUnit of the DataGrid must be set to Cell.
The DataGridmust fully generated otherwise ItemContainerGenerator returns null.
GetCellValue method works for a few UIElements considered to be more common to be used as DataGridColumn Types.

How i can get the value of cell in datagrid in wpf?

I have a datagrid, with a number of rows. I want to get the value of cell[0].
In the window form I was using this code:
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
if (dataGridView1.Rows[i].Cells[0].Value == null)
{
//do somthing
}
}
The problem is, I do not know how to get the value of the cell, as this code does not work in WPF.
Like I mentioned in the comments, you need to read more on WPF and bindings that how it works because value which you are trying to get from UI can easily be fetched from underlying data object.
Say you have binded dataGrid to some list ObservableCollection<MyObject> and first column of dataGrid is binded to property Name. You can get value for first cell simply like this:
for (int i = 0; i < dataGridView1.Items.Count; i++)
{
string value = ((MyObject)dataGridView1.Items[0]).Name;
if (String.IsNullOrEmpty(textBlock.Text))
{
// do something.
}
}
That being said, assuming first cell is simple DataGridTextColumn, you can get the value in traditional WinForms way in WPF like this:
for (int i = 0; i < dataGridView1.Items.Count; i++)
{
TextBlock textBlock = dataGridView1.Columns[0]
.GetCellContent(dataGridView1.Items[i]) as TextBlock;
if (textBlock != null)
{
if (String.IsNullOrEmpty(textBlock.Text))
{
// do something.
}
}
}
== is a comparison operator. = is used for assignment:
comboBox3.Text = dataGridView1.Rows[i].Cells[0].Value.ToString();

DataGridView issue - Calculated column value does not initially show up in DataGridView

I am developing a Windows Forms application using C#, .Net 4.5, Entity Frameworks 6.1
I am using the following code to populate at DataGridView control.
var context = new MyVisionBidModelEntities();
bidItemMaterialBindingSource.DataSource =
context.BidItemMaterials.Where(c => c.BidItemID == selectedItem.BidItemID).ToList();
dataGridView1.DataSource = bidItemMaterialBindingSource;
I then set compute the value of a "TotalPrice" column using the following code.
foreach (DataGridViewRow row in dataGridView1.Rows.Cast<DataGridViewRow>().Where(row => !row.IsNewRow))
{
CalculateTotalPrice(row);
}
private void CalculateTotalPrice(DataGridViewRow row)
{
object a = row.Cells[1].Value;
object b = row.Cells[2].Value;
object c = row.Cells[3].Value;
double aNumber = 0;
double bNumber = 0;
double cNumber = 0;
if (a != null)
aNumber = Double.Parse(a.ToString());
if (b != null)
bNumber = Double.Parse(b.ToString());
if (c != null)
cNumber = Double.Parse(c.ToString());
row.Cells["TotalPrice"].Value = aNumber * bNumber * cNumber;
row.Cells["TotalPrice"].ValueType = typeof(double);
}
When I initially view the DataGridView Control, All Rows and Columns are viewable, however, the TotalPrice Column has Null Values.
When I re-exectute the code above, the DataGridView now has the TotalPrice Values.
I have tried doing a DataGridView.Refresh, DataGridView.Update etc. But cannot make the Calculated Column show up initially. It works fine on the second paint.
Am I missing Something?
If your TotalPrice column is not bound I would make it a virtual column and do the calculation in the dataGrid's CellValueNeeded event, otherwise perform the calculation's before you set the DataGrid's DataSource property. There are still some more details you may have to workout depending on how your users will be using the grid, but this should get you going in the right direction.
on the first paint, all rows are new rows... think about changing your foreach statement.
as requested by someone else, here's the code changed for you/work done for you:
Change this block:
foreach (DataGridViewRow row in dataGridView1.Rows.Cast<DataGridViewRow>().Where(row => !row.IsNewRow))
{
CalculateTotalPrice(row);
}
for this block instead:
foreach (DataGridViewRow row in dataGridView1.Rows)
{
CalculateTotalPrice(row);
}

Clarification on how to use FirstDisplayedScrollingRowIndex

Just posted before and need clarification on a property. (Note I know this question is similar to others and hence I tried looking elsewhere for the solution but couldn't find the exact one for this situation).
I'm rather new to programming and don't know how to make a DataGridView scroll to the row selected by a user. I tried using FirstDisplayedScrollingRowIndex but am getting the following error:
Error: Cannot implicitly convert type 'System.Windows.Forms.DataGridViewRow' to 'int'
Which occurs when I try to bring the selected row by the user to the top of the datagridview:
dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.Rows[i]
Here is the full code:
String searchVal = textBox1.Text;
for (int i = 0; i < dataGridView1.RowCount; i++)
{
if (dataGridView1.Rows[i].Cells[0].Value != null && dataGridView1.Rows[i].Cells[0].Value.ToString().Contains(searchVal))
{
dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.Rows[i];
dataGridView1.Update();
}
}
According to the documentation, FirstDisplayedScrollingRowIndex:
Gets or sets the index of the row that is the first row displayed on the DataGridView.
You already have the index stored in i ... try just using that:
dataGridView1.FirstDisplayedScrollingRowIndex = i;
To address your second question in the comments, here's how you can find the first exact match (if any):
var selectedRow = dataGridView1.Rows.Cast<DataGridViewRow>()
.FirstOrDefault(x => Convert.ToString(x.Cells[0].Value) == searchVal);
if (selectedRow != null)
{
dataGridView1.FirstDisplayedScrollingRowIndex = dataGridView1.Rows[i];
dataGridView1.Update();
}
Just use i instead of dataGridView1.Rows[i]
dataGridView1.FirstDisplayedScrollingRowIndex = i;

Finding an item in asp.ListView with Value when paging is enabled

I'm trying to find the selected Item in an aspx ListView that is on a separate page, then switch the page and select the item. I have the value property of the ListViewItem I am looking for, but cannot seem to get it to work. Here is what I tried:
for (int i = 0; i < lvProject.Items.Count; i++)
{
if (((Label)lvProject.Items[i].FindControl("Project_IDLabel")).Text == project.ToString())
{
lvProject.SelectItem(i);
break;
}
}
So lvProject is my list view. The project Variable is an Int64 which represents the UID of my Project. This is also the Value of my ListViewItems. The problem with the code above is that when paging is enabled, and the item is on a different page this will not work because the listView.Items.Count is set to the # of Items on the current page only.
My goal is to find the item, set the listview to display the correct page, and finally select the item. You would figure that I could just set the SelectedValue property, but this is not that simple as it is read only. Any ideas would help greatly, thanks in advance.
--Roman
In order to get the total record count from the object data source, you should use the Selected event as follows:
protected void ObjectDataSource1_Selected(object sender, ObjectDataSourceStatusEventArgs e)
{
// Get total count from the ObjectDataSource
DataTable dt = e.ReturnValue as DataTable;
if (dt != null) recordCount = dt.Rows.Count; // recordCount being declared outside the method
}
You would then be able to search for the item as follows:
for (int i = 0; i < recordCount; i++)
{
Label lblItem = (Label)lvProject.Items[i].FindControl("IdLabel");
if (lblItem.Text.Equals(itemToSearch))
{
lvProject.SelectedIndex = i;
break;
}
}
Hope it helps!
How do you bind ListView Items?
If you are using database level paging (stored procedure, query) - you should do search in the same way - using database query/stored procedure by passing a search criteria.
If you are bind ListView Items to a collection of items which are provided by a business/data layer - you have to create search method on layer which provides items so this method will be able to loop through the items.
You should set the SelectedIndex property to i
for (int i = 0; i < lvProject.Items.Count; i++)
{
if (((Label)lvProject.Items[i].FindControl("Project_IDLabel")).Text == project.ToString())
{
lvProject.SelectedIndex = i;
break;
}
}

Categories

Resources