none
Show DB data in nested Datagrid in WPF ? RRS feed

  • Question

  • Hi every 1

    Please i'm new with WPF, i have DB with 2 tables (Customers_details,Customers_Activities) and i want my WPF (vb.net) app datagrid to do the following :

    --> inner datagrid as row details template for the 1st datagrid to show the Customer activities when user clicks the row.
    is it possible to make something like this with the same datagrid ??

    below is my code, i just cant bind the inner datagtid to the Activities datatable !

    <Grid>
            <DataGrid AutoGenerateColumns="False" Name="DataGrid1">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Customer ID" Width="100" Binding="{Binding Cus_ID}"/>
                    <DataGridTextColumn Header="Customer Name" Width="200" Binding="{Binding Cus_Name}"/>
                </DataGrid.Columns>
                <DataGrid.RowDetailsTemplate>
                    <DataTemplate>
                        <DataGrid  Name="DG1" ItemsSource"{Binding source=dt1}" >
                            <DataGridTextColumn Header="Activity ID" Width="100" Binding="{Binding Act_ID}"/>
                            <DataGridTextColumn Header="Description" Width="200" Binding="{Binding Desc}"/>
                        </DataGrid>
                    </DataTemplate>
                </DataGrid.RowDetailsTemplate>
            </DataGrid>
        </Grid>

      Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
            Dim da As New OleDbDataAdapter("select Cus_ID,Cus_Name from Customers_details", con)
            Dim dt As New DataTable
            da.Fill(dt)
            DataGrid1.ItemsSource = dt.DefaultView
        End Sub
        Private Sub DataGrid1_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles DataGrid1.SelectionChanged
            Dim drv As System.Data.DataRowView = CType(DataGrid1.SelectedItem, System.Data.DataRowView)
            Dim da1 As New OleDbDataAdapter("select Act_ID,Desc from Customers_Activities where Cus_ID='" & drv.Item(1).ToString & "'", con)
            Dim dt1 As New DataTable
            da1.Fill(dt1)
        End Sub
    please any idea,hints will be much appreciated. 


    Saturday, April 25, 2015 3:37 PM

Answers

  • Hi Mohammed,

    In my experience, I suggest that you could define CustomDetals class and CustomActivitis class according to your 2 tables. Then you could convert data to collection of your custom class when you got data from database.

    I have made a code sample for you. But I’m a C# developer, so I have converted my code to VB. If the code has some errors, you need to edit it. Thank you for your understanding.

    Here is my code sample. You could refer to it.

    <DataGrid AutoGenerateColumns="False" Name="DataGrid1">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Customer ID" Width="100" Binding="{Binding Cus_ID}"/>
                    <DataGridTextColumn Header="Customer Name" Width="200" Binding="{Binding Cus_Name}"/>
                </DataGrid.Columns>
                <DataGrid.RowDetailsTemplate>
                    <DataTemplate>
                        <DataGrid ItemsSource="{Binding CustomActivityColl}" AutoGenerateColumns="False">
                            <DataGrid.Columns>
                                <DataGridTextColumn Header="Activity ID" Width="100" Binding="{Binding Act_ID}"/>
                                <DataGridTextColumn Header="Description" Width="200" Binding="{Binding Desc}"/>
                            </DataGrid.Columns>
                            
                        </DataGrid>
                    </DataTemplate>
                </DataGrid.RowDetailsTemplate>
            </DataGrid>
    Public Class CustomDetails
        Public Property Cus_ID() As String
            Get
                Return m_Cus_ID
            End Get
            Set
                m_Cus_ID = Value
            End Set
        End Property
        Private m_Cus_ID As String
        Public Property Cus_Name() As String
            Get
                Return m_Cus_Name
            End Get
            Set
                m_Cus_Name = Value
            End Set
        End Property
        Private m_Cus_Name As String
    
        Public Property CustomActivityColl() As List(Of CustomActivities)
            Get
                Return m_CustomActivityColl
            End Get
            Set
                m_CustomActivityColl = Value
            End Set
        End Property
        Private m_CustomActivityColl As List(Of CustomActivities)
    
        Public Function GetData() As List(Of CustomDetails)
            Dim customs As New List(Of CustomDetails)()
            customs.Add(New CustomDetails() With {
                Key .Cus_ID = "1",
                Key .Cus_Name = "abc",
                Key .CustomActivityColl = New List(Of CustomActivities)() From { 
                    New CustomActivities() With { 
                        Key .Act_ID = "1", 
                        Key .Desc = "abcdefdg"
                    } 
                } 
            })
            Return customs
        End Function
    End Class
    
    Public Class CustomActivities
    	Public Property Act_ID() As String
    		Get
    			Return m_Act_ID
    		End Get
    		Set
    			m_Act_ID = Value
    		End Set
    	End Property
    	Private m_Act_ID As String
    	Public Property Desc() As String
    		Get
    			Return m_Desc
    		End Get
    		Set
    			m_Desc = Value
    		End Set
    	End Property
    	Private m_Desc As String
    End Class
    
    Dim customs As List(Of CustomDetails) = New CustomDetails().GetData()
    	DataGrid1.ItemsSource = customs
    

    I hope my reply would be helpful to you.

    Best Regards,

    Xavier Eoro


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, April 27, 2015 5:20 AM
    Moderator

All replies

  • You want the rowdetails to be a collection in each of the rows.

    Each of the Customer_Details will be expected to have some sort of a collection within it of Customer_Activities.

    I recommend you consider entity framework rather than data adapters.

    All those xxxxx adapter things aren't really suitable for professional development.

    They're great for drag and drop demonstrations where someone has to go "see how easy this is" and get some data on screen in seconds.

    Not so great in a real life application where you then have nowhere to put any business logic or adapter logic.

    Also  - the vast majority of wpf developers use the mvvm pattern.

    I definitely would recommend you take a look at it.

    I do c# so you might have difficulty following any of my code.

    Essentially, EF would give me a model with regular classes there containing collections corresponding to relationships between tables.


    Hope that helps.

    Technet articles: Uneventful MVVM; All my Technet Articles

    Saturday, April 25, 2015 3:50 PM
    Moderator
  • Thanx for your replay 

    i know that you want to help me with much better programming technique (EF) but i really wanna complete my app with datadapters , plz any idea of how to bind the data to the inner datagrid 


    Saturday, April 25, 2015 5:49 PM
  • I think it's harder with dataadapters.

    I may well be missing something since it's like 13 years since I used a dataadapter on a live app.

    I think you possibly want to work with a dataset and set up a relationship between the two datatables in that.

    http://stackoverflow.com/questions/10126602/how-to-display-related-data-from-dataset-in-wpf-datagrid

    http://jelle.druyts.net/2005/01/14/BindingTheChildRowsOfADataRow.aspx


    Hope that helps.

    Technet articles: Uneventful MVVM; All my Technet Articles

    Sunday, April 26, 2015 4:09 PM
    Moderator
  • Hi Mohammed,

    In my experience, I suggest that you could define CustomDetals class and CustomActivitis class according to your 2 tables. Then you could convert data to collection of your custom class when you got data from database.

    I have made a code sample for you. But I’m a C# developer, so I have converted my code to VB. If the code has some errors, you need to edit it. Thank you for your understanding.

    Here is my code sample. You could refer to it.

    <DataGrid AutoGenerateColumns="False" Name="DataGrid1">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Customer ID" Width="100" Binding="{Binding Cus_ID}"/>
                    <DataGridTextColumn Header="Customer Name" Width="200" Binding="{Binding Cus_Name}"/>
                </DataGrid.Columns>
                <DataGrid.RowDetailsTemplate>
                    <DataTemplate>
                        <DataGrid ItemsSource="{Binding CustomActivityColl}" AutoGenerateColumns="False">
                            <DataGrid.Columns>
                                <DataGridTextColumn Header="Activity ID" Width="100" Binding="{Binding Act_ID}"/>
                                <DataGridTextColumn Header="Description" Width="200" Binding="{Binding Desc}"/>
                            </DataGrid.Columns>
                            
                        </DataGrid>
                    </DataTemplate>
                </DataGrid.RowDetailsTemplate>
            </DataGrid>
    Public Class CustomDetails
        Public Property Cus_ID() As String
            Get
                Return m_Cus_ID
            End Get
            Set
                m_Cus_ID = Value
            End Set
        End Property
        Private m_Cus_ID As String
        Public Property Cus_Name() As String
            Get
                Return m_Cus_Name
            End Get
            Set
                m_Cus_Name = Value
            End Set
        End Property
        Private m_Cus_Name As String
    
        Public Property CustomActivityColl() As List(Of CustomActivities)
            Get
                Return m_CustomActivityColl
            End Get
            Set
                m_CustomActivityColl = Value
            End Set
        End Property
        Private m_CustomActivityColl As List(Of CustomActivities)
    
        Public Function GetData() As List(Of CustomDetails)
            Dim customs As New List(Of CustomDetails)()
            customs.Add(New CustomDetails() With {
                Key .Cus_ID = "1",
                Key .Cus_Name = "abc",
                Key .CustomActivityColl = New List(Of CustomActivities)() From { 
                    New CustomActivities() With { 
                        Key .Act_ID = "1", 
                        Key .Desc = "abcdefdg"
                    } 
                } 
            })
            Return customs
        End Function
    End Class
    
    Public Class CustomActivities
    	Public Property Act_ID() As String
    		Get
    			Return m_Act_ID
    		End Get
    		Set
    			m_Act_ID = Value
    		End Set
    	End Property
    	Private m_Act_ID As String
    	Public Property Desc() As String
    		Get
    			Return m_Desc
    		End Get
    		Set
    			m_Desc = Value
    		End Set
    	End Property
    	Private m_Desc As String
    End Class
    
    Dim customs As List(Of CustomDetails) = New CustomDetails().GetData()
    	DataGrid1.ItemsSource = customs
    

    I hope my reply would be helpful to you.

    Best Regards,

    Xavier Eoro


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, April 27, 2015 5:20 AM
    Moderator
  • Many thanks Xavier you made my day 

    Monday, April 27, 2015 1:27 PM