# .NET and More > WPF, WCF, WF >  Get Value from DataGrid Cell (WPF)

## Omega123

I am looking for a way to read the value of allways one specific cell (Row:0, Column 2) in a DataGrid.

In WinForms it was very easy:




> var1 = DataGridView1.Item(2, 0).Value


I am searching for hours now without finding anything usefull. It is important that I can choose values programatically, like in the way above, without preselections with mouse etc.

I hope someone knows an answer to that

Regards

----------


## KGComputers

Hello,

Welcome to the forums!  :Smilie: 

To get the cell value of winforms datagridview is straightforward. In WPF, you need to access the Visual Tree (hierarchy of elements) of the datagrid down to
the datagridcell.

Download the project in my codebank submission: Accessing Rows and Cells in a WPF DataGrid and put the code below inside the SetColorCell() method.


VB.NET Code:
Dim cell As DataGridCell = TryCast(grid1.Columns(1).GetCellContent(grid1.GetRow(0)).Parent, DataGridCell)Dim name As String = TryCast(cell.Content, TextBlock).TextMessageBox.Show(name)

Note: The code above, retrieves the cell value in row 0 column 1. 

- kgc

----------


## Omega123

Thank you for this solution kgc,

isn't there a simpler way? - 300+ lines of code vs. 1, this just shouldn 't be.

omega

----------


## KGComputers

> isn't there a simpler way? - 300+ lines of code vs. 1, this just shouldn 't be.


If you browse and debug through the code, you only need this function in order for the code in post #2 to work.


VB.NET Code:
<Extension()>    Function GetRow(ByVal grid As DataGrid, ByVal index As Integer) As DataGridRow         Dim row As DataGridRow = DirectCast(grid.ItemContainerGenerator.ContainerFromIndex(index), DataGridRow)        If row Is Nothing Then            grid.UpdateLayout()            grid.ScrollIntoView(grid.Items(index))            row = DirectCast(grid.ItemContainerGenerator.ContainerFromIndex(index), DataGridRow)        End If         Return row    End Function

But if you insist on one liner solution, maybe you can do some search in MSDN docs. Maybe you can come up with something.

By the way, are you binding a DataTable object to the ItemSource of your DataGrid? Or List<T>? Or Observable Collection?

- kgc

----------


## KGComputers

Aha, you can do it in one line. Given that your DataGrid's ItemSource is assigned with a DataTable object and your grid has few number of rows. All of them visible inside the grid.


VB.NET Code:
Dim namePerson = TryCast(grid1.Items(0), DataRowView).Row.Item(1).ToString()MessageBox.Show(namePerson)

However, the code above might have some issues given that the grid has hundreds of rows and those rows will be visible once
you scroll through. The one liner code does not have a ScrollIntoView() method applied. So I still prefer using the extension method in post #4.

- kgc

----------


## Omega123

Thank you for your effort to help me out on this!

This is the code from you I implemented.
Unfortunatelly I am note able to execute it.


Error BC30456	"GetRow" is not a member of "DataGrid".

(bgdatagrid_ArtikelInf.GetRow(0)).Parent, DataGridCell)





```
            
     Private Sub btn_tc1_ENTER_Click(sender As Object, e As RoutedEventArgs) Handles btn_tc1_ENTER.Click

            Dim cell As DataGridCell = TryCast(bgdatagrid_ArtikelInf.Columns(2).GetCellContent(bgdatagrid_ArtikelInf.GetRow(0)).Parent, DataGridCell)
            Dim name As String = TryCast(cell.Content, TextBlock).Text
            MessageBox.Show(name)


        End If
    End Sub

    '<Extension()>
    Function GetRow(ByVal grid As DataGrid, ByVal index As Integer) As DataGridRow

        Dim row As DataGridRow = DirectCast(grid.ItemContainerGenerator.ContainerFromIndex(index), DataGridRow)
        If row Is Nothing Then
            grid.UpdateLayout()
            grid.ScrollIntoView(grid.Items(index))
            row = DirectCast(grid.ItemContainerGenerator.ContainerFromIndex(index), DataGridRow)
        End If

        Return row
    End Function
```


Omega

----------


## homer13j

> Error BC30456	"GetRow" is not a member of "DataGrid".
> 
> 
> 
> 
> ```
>             
>     '<Extension()>
> ```


Your Extension attribute is commented out. Remove the apostrophe and it should work.

----------


## KGComputers

And make sure to import CompilerServices namespace.


VB.NET Code:
Imports System.Runtime.CompilerServices

----------


## Omega123

Good morning,

- the code I posted above is in MainWindow.xaml.vb
- The name of my DataGrid = bgdatagrid_ArtikelInf
- Imports System.Runtime.CompilerServices is above the class in MainWindow.xaml.vb
- <Extension()>    (without apostrophe) I  have no clue what this actually does

- This is the hole code inside MainWindow.xaml.vb





> Private Sub btn_tc1_ENTER_Click(sender As Object, e As RoutedEventArgs) Handles btn_tc1_ENTER.Click
>         Me.ArtikelAuftrag = TextBox1.Text
> 
>         'MsgBox(ArtikelAuftrag)
> 
>         Dim con As String = "Server=FHPCzz\SQLEXPRESS;Database=zzz;User=zzz;Pwd=zzz;"
>         Dim connection As New SqlConnection(con)
> 
>         If Me.ArtikelAuftrag.Contains("#") Then
> ...



VS throws two errors marked in RED so no compiling is posible:


ERROR	BC36551	extended methods can only be defined in Modules

ERROR       BC30311	The Value of type "Integer" can not be converted into "UIElement"




Omega

----------


## KGComputers

> ERROR    BC36551    extended methods can only be defined in Modules


Create an empty module in your project called DataGridExtensions and transfer the GetRow() function from MainWindow.Xaml.vb to DataGridExtensions.vb module just like in my example project.


VB.NET Code:
Imports System.Runtime.CompilerServices Module DataGridExtensions   <Extension()>    Function GetRow(ByVal grid As DataGrid, ByVal index As Integer) As DataGridRow         Dim row As DataGridRow = DirectCast(grid.ItemContainerGenerator.ContainerFromIndex(index), DataGridRow)        If row Is Nothing Then            grid.UpdateLayout()            grid.ScrollIntoView(grid.Items(index))            row = DirectCast(grid.ItemContainerGenerator.ContainerFromIndex(index), DataGridRow)        End If         Return row    End Function End Module




> ERROR BC30311    The Value of type "Integer" can not be converted into "UIElement"


Your using the Grid class "*Grid.GetRow(0)*" instead of your grid object when referencing GetRow() method which is wrong. Replace it with your grid object such as below:


vb.net Code:
Dim cell As DataGridCell = TryCast(bgdatagrid_ArtikelInf.Columns(2).GetCellContent(bgdatagrid_ArtikelInf.GetRow(0)).Parent, DataGridCell)

----------


## Omega123

ok we are getting somewhere, :Smilie: 

no errors before execution, but when I run the application I get the following:

Zusätzliche Informationen: Der Index lag außerhalb des Bereichs. Er darf nicht negativ und kleiner als die Auflistung sein.
(translation: The index is out of the range. I shouldn't be negative or smaller than the list)

I tried to change the indices but no luck with that.

----------


## KGComputers

Trace and debug your code. It must have something to do with datagrid's databinding. It could be that the datagrid has no rows at all when you access the row and column.

-kgc

----------


## Omega123

yuhuuuu!  :Smilie:  Its working!,
thank you very much!!

there is one little issue left - the datagrid is on a different tab. That means to only way to get the value of the specific cell is to run your function when you are on the same tab as the datagrid.
Otherwise it throws the exception in my last post.

Is there a way around this?

Thank you again

----------


## KGComputers

Maybe you can do some readings on how to navigate through the Tab's Visual Tree to access the DataGrid object. Just like the method GetVisualChild() in DataGridExtensions.vb from post #2.

----------

