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