在数据网格上选择具有分组数据的行

时间:2015-09-17 21:35:14

标签: wpf wpfdatagrid

我已经在线搜索并尝试过自己,并且无法通过在具有分组数据的数据网格上提供搜索值来找到准确选择记录编程的方法。我在下面的代码处理未分组的数据,但是当数据被分组时,索引似乎不再有效,并且分组似乎对数据的索引有效。

以下是表单的屏幕截图。数据被分组。用户键入销售订单编号并单击查找按钮。我想记录为该行突出显示的内容。

enter image description here

这是在找到记录时未分组的数据,您可以看到该记录突出显示:

enter image description here

以下是我的代码。单击“查找”按钮时会触发OnSelectionButtonClick事件。数据在cmdAddRemoveGroup_Click过程中分组/取消分组。数据绑定到RebindData过程中的网格。销售订单将传递到SelectGridRow过程以选择找到的行。

任何帮助表示赞赏! 谢谢,吉米

'Module level scope
Private da As wpfProductionDashboard.flexDataSetTableAdapters.vwProductionScheduleWPFMainTableAdapter = New wpfProductionDashboard.flexDataSetTableAdapters.vwProductionScheduleWPFMainTableAdapter()

Private Sub OnSelectionButtonClick(sender As Object, e As RoutedEventArgs)
        Try
            Dim so As Integer = Convert.ToInt32(Me.txtFind.Text)

            Dim index As Integer = FlexDataSet.vwProductionScheduleWPFMain.Rows.IndexOf(FlexDataSet.vwProductionScheduleWPFMain.Rows.Find(so))

            'Dim index2 As Integer = 1

            'For Each c In FlexDataSet.vwProductionScheduleWPFMain.Rows
            '    If c(0) = so Then
            '        SelectGridRow(dataGrid1, index2)
            '        Exit Sub
            '    End If
            '    Console.WriteLine(c(0))
            '    index2 += 1
            'Next
            If index > 0 Then
                Console.WriteLine(index.ToString())
                SelectGridRow(dataGrid1, index)
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Find button click error", MessageBoxButton.OK, MessageBoxImage.Error)
        End Try
    End Sub

    Private Sub SelectGridRow(ByVal DataGrid As DataGrid, ByVal rowIndex As Integer)
        If Not DataGrid.SelectionUnit.Equals(DataGridSelectionUnit.FullRow) Then
            Throw New ArgumentException("The SelectionUnit of the DataGrid must be set to FullRow.")
        End If

        If rowIndex < 0 OrElse rowIndex > (DataGrid.Items.Count - 1) Then
            Throw New ArgumentException(String.Format("{0} is an invalid row index.", rowIndex))
        End If

        DataGrid.SelectedItems.Clear()

        Dim item As Object = DataGrid.Items(rowIndex)

        DataGrid.SelectedItem = item

        Dim row As DataGridRow = TryCast(DataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex), DataGridRow)
        If row Is Nothing Then
            ' bring the data item into view
            DataGrid.ScrollIntoView(item)
            row = TryCast(DataGrid.ItemContainerGenerator.ContainerFromIndex(rowIndex), DataGridRow)
        End If
    End Sub

    Private Sub cmdAddRemoveGroup_Click(sender As Object, e As RoutedEventArgs) Handles cmdAddRemoveGroup.Click
        Try
            If cmdAddRemoveGroup.IsChecked = False Then
                FlexDataSet.vwProductionScheduleWPFMain.DefaultView.RowFilter = "SalesOrderStatus <> 'Hold' and SalesOrderStatus <> 'Approval Done'"
                vw.GroupDescriptions.Add(New PropertyGroupDescription("SalesOrderStatusGroup", New OpenStatusConverter))
            Else
                vw.GroupDescriptions.Clear()
            End If
            SortDataGrid()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Grouping Event", MessageBoxButton.OK, MessageBoxImage.Error)
        End Try
    End Sub

    Private Sub RebindData()
        Try
            Dim taStatuses As wpfProductionDashboard.flexDataSetTableAdapters.spGetProductionDashboardStatusesTableAdapter = New wpfProductionDashboard.flexDataSetTableAdapters.spGetProductionDashboardStatusesTableAdapter()

            da.Fill(FlexDataSet.vwProductionScheduleWPFMain)
            taStatuses.Fill(FlexDataSet.spGetProductionDashboardStatuses)

            vw.View.MoveCurrentToFirst()
            cvOrderStatuses.View.MoveCurrentToFirst()

            lstOrderStatus.ItemsSource = cvOrderStatuses.View
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Rebind Data Event", MessageBoxButton.OK, MessageBoxImage.Error)
        End Try
    End Sub

谢谢康斯坦丁。我担心你会这么说。我还没弄清楚如何实现ObservableCollection,因为这个应用程序没有使用MVVM。如果你不介意,我明白你是否愿意,你会介意试着帮助我看看我是否可以通过我当前的实施绑定到ObservableCollection吗?以下是我的xaml和解释。

<Window.Resources>
<local:flex2kSQLDataSet x:Key="Flex2kSQLDataSet" />
<CollectionViewSource x:Key="cvOrderStatuses" Source="{Binding spGetProductionDashboardStatuses, Source={StaticResource Flex2kSQLDataSet}}" />
<CollectionViewSource x:Key="VwProductionScheduleWPFMainViewSource" Source="{Binding vwProductionScheduleWPFMain, Source={StaticResource Flex2kSQLDataSet}}" />

<Grid DataContext="{StaticResource VwProductionScheduleWPFMainViewSource}">

VwProductionScheduleWPFMainViewSource使用SQL Server视图和表适配器。是否可以使用此视图并创建ObservableCollection并将其绑定到datagrid?如果是这样,如果您可以提供代码建议或指出我正确的方向,我将非常感激!

更新#3: 康斯坦丁,我想我已经接近但需要更多的帮助。

模块级别:     私有物品作为对象

Private Property Items() As ObservableCollection(Of vwProductionScheduleWPFMain)
    Get
        Return m_Items
    End Get
    Set(value As ObservableCollection(Of vwProductionScheduleWPFMain))
        m_Items = value
    End Set
End Property

Private m_Items As ObservableCollection(Of vwProductionScheduleWPFMain)

表单加载:     Private Sub Window_Loaded(sender as Object,e As RoutedEventArgs)处理MyBase.Loaded         尝试

        dataGrid1.DataContext = Me

绑定数据程序:     私有子绑定数据()         尝试             Dim db As TFCDataContext

        db = New TFCDataContext

        Items = New ObservableCollection(Of vwProductionScheduleWPFMain)(db.vwProductionScheduleWPFMains)
        dataGrid1.ItemsSource = Items

查找程序:     Private Sub OnSelectionButtonClick(发送者为对象,e为RoutedEventArgs)         尝试             Dim so Integer = Convert.ToInt32(Me.txtFind.Text)

        Item = Items.Where(Function(x) x.SalesOrder = so)
        dataGrid1.SelectedItem = Item

    Catch ex As Exception
        MessageBox.Show(ex.Message, "Find button click error", MessageBoxButton.OK, MessageBoxImage.Error)
    End Try
End Sub

网格的XAML:     

我能够看到我的Items observable集合正在获取正确的数据,并且find方法成功找到了记录。但是,找到的记录不会选择网格中的记录。我错过了什么让它找到网格中的记录?

另外,我注意到如果我删除了在load事件上设置DataContext,那么仍然会加载数据。是否需要将DataContext设置为(me / this),还是我做错了?再次感谢您的帮助!

更新#4: 我已成功找到在可观察Items集合中搜索的项目并将其分配给对象Item,但是当我设置datagrid的SelectedItem属性时,未选择该行,这是我真正需要的。如果您可以提供帮助或提供示例代码,我们将不胜感激。下面是我的代码,显示已找到该项目(但未选择该行)。

enter image description here

设置了ItemSource和SelectedItem的数据网格的XAML:

<DataGrid x:Name="dataGrid1"
AutoGenerateColumns="False"
CanUserReorderColumns="True"
CanUserAddRows="False"
IsReadOnly="False"
CanUserResizeColumns="True"
EnableRowVirtualization="True"
ItemsSource="{Binding Items}"
SelectedItem="{Binding Item}"
CanUserSortColumns="True"
RowHeight="25"
Margin="10,15,10,10"
Grid.Row="3"
Sorting="DataGrid_Standard_Sorting">

2 个答案:

答案 0 :(得分:1)

尝试执行以下操作(我将在此处使用c#,但它对于vb.net几乎完全相同)

  1. 您的DataGrid定义应该是这样的:
  2. <DataGrid ItemsSource="{Binding Items}" SelectedItem="{Binding Item}" .../>

    1. 当您搜索时,只需这样做:
    2. Item = Items.Where(p=> ...);

      1. 然后,根据您的代码的实现,您应该只将DataGrid滚动到选定的行
      2. 希望有所帮助

答案 1 :(得分:0)

ObservableCollection是最佳实现。下面的示例代码。

Public Property MyCollection() As ObservableCollection(Of YourClass)
    Get
        Return m_MyCollection
    End Get
    Set(value As ObservableCollection(Of YourClass))
        m_MyCollection = value
    End Set
End Property
Private m_MyCollection As New ObservableCollection(Of YourClass)

Dim findItem As YourClass

findItem = MyCollection.First(Function(x) x.SalesOrder = so)

dataGrid1.SelectedItem = findItem

dataGrid1.ScrollIntoView(findItem)