WPF VBnet comboBox dataGrid retrieve value

30 Views Asked by At

Edit : Succeed thanks to user's comment, see below :

First time posting on StackOverflow. I hope I did it well.

Context : I'm not a professionnal programmer. I use coding for automating my job. I mainly use VBA. It is why I used VB.NET and not C#. I need to use WPF for the graphical interface, not Winforms.

I have a DataGrid which contains a ComboBox. I need to get the selected value of the ComboBox.

Everything I tried to achieve has failed despite the help of tons of web research and deep conversations with our fellow ChatGPT.

I tried to do MVVM but failed it. I want to avoid using it.

I apologize in advance for the code syntax you are about to see. Remain seated.

My problem is that the result of comboBox = TryCast(cell.Content, ComboBox) is Nothing which means I will never get cellValue = item.Type(comboBox.SelectedItem).

Here is what I have done :

XAML part :

<DataGrid Style="{DynamicResource DataGridStyleAssistantDevis}" Name ="dataGridInvestigations" 
          HorizontalAlignment="Left" VerticalAlignment="Top"
          Height="535" Width="401" Margin="275,303,0,0" 
          FontSize="12" FontWeight="Bold"
          Foreground="Black"
          BorderBrush="white" BorderThickness="1"
          HeadersVisibility="Column"
          AutoGenerateColumns="False"
          SelectionMode="Single" 
          SelectionUnit="Cell"
          CanUserAddRows="False"
          CanUserDeleteRows="False"
          CanUserResizeColumns="False"
          CanUserReorderColumns="False"
          ScrollViewer.CanContentScroll="False"
          VerticalScrollBarVisibility="Disabled" Grid.RowSpan="2" >
    <DataGrid.ColumnHeaderStyle>
        <Style TargetType="DataGridColumnHeader">
            <Setter Property="Height" Value="34"/>
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
            <!-- Définition de la hauteur du header -->
        </Style>
    </DataGrid.ColumnHeaderStyle>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Unite" 
                            Binding="{Binding Unite}" 
                            Width="60" 
                            CanUserSort="False"/>
        <!-- Define DataGridTemplateColumn for ComboBox -->
        <DataGridTemplateColumn Header="Type" 
                                Width="260" 
                                CanUserSort="False">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox x:Name="comboBoxDataGrid" 
                              ItemsSource="{Binding Type}"
                              SelectedItem="{Binding Type}"
                              Style="{DynamicResource ComboBoxStyleAssistantDevis}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn Header="Profondeur" 
                            Binding="{Binding Profondeur}" 
                            Width="79" 
                            CanUserSort="False"/>
    </DataGrid.Columns>
</DataGrid>

Then, in the code behind :

Public Class Item
    Public Property Unite As String
    Public Property Type As String()
    'Public Property Type As List(Of String)
    Public Property Profondeur As String
End Class

Class MainWindow
    Sub New()
        InitializeComponent()
        Dim items As New ObservableCollection(Of Item)()
        items.Add(New Item() With {.Unite = "", .Type = {"A", "B", "C", "D", "E", "F")"}, .Profondeur = ""})
        items.Add(New Item() With {.Unite = "", .Type = {"A", "B", "C", "D", "E", "F")"},  .Profondeur = ""})
        dataGridInvestigations.ItemsSource = items
    End Sub

    Private Sub ButtonClickRedactionDevis(sender As Object, e As RoutedEventArgs)

        Dim investigations(18, 3) As String
        Dim NbRow As Integer
        Dim NbColumn As Integer
        Dim cellValue As String

        Dim comboBox As ComboBox
        Dim cell As DataGridCell

        cellValue = ""

        For NbRow = 1 To 18
            ' Obtenir l'objet de données de la ligne actuelle :
            Dim item As Assistant_Devis.Item = CType(dataGridInvestigations.Items(NbRow  - 1), Assistant_Devis.Item)

            For NbColumn = 1 To 3

                Select Case NbColumn 
                    Case 1
                        cellValue = item.Unite.ToString()
                    Case 2
                        'cell = dataGridInvestigations(NbRow , NbColumn )
                        dataGridInvestigations.CurrentCell = New DataGridCellInfo(dataGridInvestigations.Items(NbRow), dataGridInvestigations.Columns(NbColumn ))
                        dataGridInvestigations.UpdateLayout()
                        cell = dataGridInvestigations.Columns(NbColumn-1).GetCellContent(dataGridInvestigations.Items(NbRow- 1)).Parent
                        comboBox = TryCast(cell.Content, ComboBox)
                        If comboBox IsNot Nothing Then
                            cellValue = item.Type(comboBox.SelectedItem)
                        Else
                            cellValue = ""
                        End If
                    Case 3
                        cellValue = item.Profondeur.ToString()
                End Select

                investigations(NbRow, NbColumn) = cellValue
            Next
        Next
    End Sub

End Class

Edit : First, I need to thank user246821 for his comments that led me to finding the answer. It is true that C# is way more documented than VB.NET. But I disagree with user246821 on ChatGPT's usefulness. For a non-professionnal and noobie programmer like myself, LLMs are extremely powerful, allowing us to get on the horse. Doesn't make you a rider though. LLMs are better on massive data. So I asked it to find the solution in C#, and then, write it in VB.NET. Here is the solution of my problem (check the ComboBox in WPF & VB.NET) :

XAML part :

<DataGrid Style="{DynamicResource DataGridStyleAssistantDevis}" 
          Name ="dataGridInvestigations" 
          ItemsSource="{Binding Items}"
          HorizontalAlignment="Left" VerticalAlignment="Top"
          Height="535" Width="401" Margin="275,303,0,0" 
          FontSize="12" FontWeight="Bold"
          Foreground="Black"
          BorderBrush="white" BorderThickness="1"
          HeadersVisibility="Column"
          AutoGenerateColumns="False"
          SelectionMode="Single" 
          SelectionUnit="Cell"
          CanUserAddRows="False"
          CanUserDeleteRows="False"
          CanUserResizeColumns="False"
          CanUserReorderColumns="False"
          ScrollViewer.CanContentScroll="False"
          VerticalScrollBarVisibility="Disabled" Grid.RowSpan="2" >
    <DataGrid.ColumnHeaderStyle>
        <Style TargetType="DataGridColumnHeader">
            <Setter Property="Height" Value="34"/>
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
            <!-- Définition de la hauteur du header -->
        </Style>
    </DataGrid.ColumnHeaderStyle>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Unite" 
                            Binding="{Binding Unite}" 
                            Width="60" 
                            CanUserSort="False"/>
        <!-- Define DataGridTemplateColumn for ComboBox -->
        <DataGridTemplateColumn Header="Type" 
                                Width="260" 
                                CanUserSort="False">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox x:Name="comboBoxDataGrid" 
                              ItemsSource="{Binding TypeOptions}"
                              SelectedItem="{Binding TypeSelectedItem, UpdateSourceTrigger=PropertyChanged}"
                              Style="{DynamicResource ComboBoxStyleAssistantDevis}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn Header="Profondeur" 
                            Binding="{Binding Profondeur}" 
                            Width="79" 
                            CanUserSort="False"/>
    </DataGrid.Columns>
</DataGrid>

VB.NET part:

Class MainWindow

    Sub New()
        InitializeComponent()

        Items = New ObservableCollection(Of Item)()
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})
        Items.Add(New Item() With {.Unite = "", .Profondeur = ""})

        DataContext = Me

    End Sub

    Private Sub ButtonClickRedactionDevis(sender As Object, e As RoutedEventArgs)

        Dim investigations(18, 3) As String
        Dim NbLignes As Integer

        Dim Unite As String
        Dim typeSelectedValue As String
        Dim Profondeur As String

        typeSelectedValue = ""

        For NbLignes = 1 To 18
            'Récupération des propriétés dans Item :
            Dim firstItem As Item
            firstItem = DirectCast(dataGridInvestigations.Items(NbLignes - 1), Item)
            'Récupération Unité :
            Unite = firstItem.Unite
            'Récupération Type :
            typeSelectedValue = firstItem.TypeSelectedItem
            'Récupération Profondeur :
            Profondeur = firstItem.Profondeur

            'Enregistrement :
            investigations(NbLignes, 1) = Unite
            investigations(NbLignes, 2) = typeSelectedValue
            investigations(NbLignes, 3) = Profondeur
        Next
    End Sub
End Class

Public Class Item
    Public Property Unite As String
    Public Property TypeOptions As ObservableCollection(Of String)
    Public Property TypeSelectedItem As String
    Public Property Profondeur As String

    Public Sub New()
        TypeOptions = New ObservableCollection(Of String)() From {"A", "B", "C", "D", "E", "F"}
    End Sub
End Class
0

There are 0 best solutions below