如何在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
相关产品推荐
相关产品推荐

