You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WPF VB.NET中获取DataGrid内嵌ComboBox的选中值?

解决WPF DataGrid内嵌ComboBox无法获取选中值的问题

作为业余开发者,日常用VBA实现工作自动化,转用VB.NET开发WPF界面时,遇到DataGrid内嵌ComboBox无法获取选中值的问题:原代码中comboBox = TryCast(cell.Content, ComboBox)返回Nothing,无法获取选中项。尝试MVVM模式失败后,通过调整数据绑定逻辑与Item类结构,成功解决该问题,以下是问题复现及完整解决方案:

原问题代码

XAML代码

<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"/>
            <!-- 定义表头高度 -->
        </Style>
    </DataGrid.ColumnHeaderStyle>
    <DataGrid.Columns>
        <DataGridTextColumn Header="单位" 
                            Binding="{Binding Unite}" 
                            Width="60" 
                            CanUserSort="False"/>
        <!-- 为ComboBox定义DataGridTemplateColumn -->
        <DataGridTemplateColumn Header="类型" 
                                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="深度" 
                            Binding="{Binding Profondeur}" 
                            Width="79" 
                            CanUserSort="False"/>
    </DataGrid.Columns>
</DataGrid>

VB.NET代码

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
            ' 获取当前行的数据对象:
            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

解决方案代码

XAML代码

<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"/>
            <!-- 定义表头高度 -->
        </Style>
    </DataGrid.ColumnHeaderStyle>
    <DataGrid.Columns>
        <DataGridTextColumn Header="单位" 
                            Binding="{Binding Unite}" 
                            Width="60" 
                            CanUserSort="False"/>
        <!-- 为ComboBox定义DataGridTemplateColumn -->
        <DataGridTemplateColumn Header="类型" 
                                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="深度" 
                            Binding="{Binding Profondeur}" 
                            Width="79" 
                            CanUserSort="False"/>
    </DataGrid.Columns>
</DataGrid>

VB.NET代码

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
            ' 获取Item中的属性:
            Dim firstItem As Item
            firstItem = DirectCast(dataGridInvestigations.Items(NbLignes - 1), Item)
            ' 获取单位:
            Unite = firstItem.Unite
            ' 获取选中的类型:
            typeSelectedValue = firstItem.TypeSelectedItem
            ' 获取深度:
            Profondeur = firstItem.Profondeur

            ' 保存到数组:
            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

内容的提问来源于stack exchange,提问作者Kony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 14:17:04