2013-10-18 64 views
0

WPF/VB.net新手在这里。WPF中的过滤项目在VB.net datagrid

我想筛选数据网格中的行并玩得开心。

我已经成功创建了一个对象列表,并使用itemsource属性来获取要填充的数据网格。

现在我有一个复选框,为了参数 - 我只想点击并过滤只符合这个标准的那些行。

通过下面的代码,我得到了一般性的“对象引用未设置为对象的实例”。错误,但有点丢失。我相信一个VB专业人士会看到它。

我宁愿在代码中做更多,而不是尽可能使用XAML。

这是我的XAML:

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 

    <Grid> 
     <DataGrid x:Name="displayGrid" HorizontalAlignment="Left" Margin="62,94,0,0" VerticalAlignment="Top" Height="142" Width="360" SelectionChanged="DataGrid_SelectionChanged"/> 
     <Button Content="Load" HorizontalAlignment="Left" Margin="62,51,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/> 
     <CheckBox x:Name="showOnlyChildren" Content="Show Only Children" HorizontalAlignment="Left" Margin="172,51,0,0" VerticalAlignment="Top" Width="147"/> 

    </Grid> 
</Window> 

这是我的代码:

Class MainWindow 

    Class person 

     Property name 
     Property age 

    End Class 

    Dim listOfPersons As New List(Of person) 
    Private filteredList As CollectionViewSource 

    Private Sub DataGrid_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) 

    End Sub 

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

     Dim aPerson As New person With { 
      .name = "Fred Smith", 
      .age = 12} 

     listOfPersons.Add(aPerson) 

     Dim bPerson As New person With { 
     .name = "Tom Jones", 
     .age = 50} 

     listOfPersons.Add(bPerson) 

     displayGrid.ItemsSource = CollectionViewSource.GetDefaultView(listOfPersons) 

    End Sub 


    Private Sub ShowOnlyChildrenFilter(ByVal sender As Object, ByVal e As FilterEventArgs) 
     Dim person As person = TryCast(e.Item, person) 
     If person IsNot Nothing Then 
      ' Filter out persons with age less than 18 
      If person.age < 19 Then 
       e.Accepted = True 
      Else 
       e.Accepted = False 
      End If 
     End If 
    End Sub 


    Private Sub AddFiltering(ByVal sender As Object, ByVal args As RoutedEventArgs) Handles showOnlyChildren.Checked 
     AddHandler filteredList.Filter, AddressOf ShowOnlyChildrenFilter 
    End Sub 

    Private Sub RemoveFiltering(ByVal sender As Object, ByVal args As RoutedEventArgs) 
     RemoveHandler filteredList.Filter, AddressOf ShowOnlyChildrenFilter 
    End Sub 




End Class 

编辑:OK缓慢而稳步地到达那里。我加入了一些变化,我发现here和感谢帮助我来到这里....这是代码看起来像现在:

Imports System.ComponentModel 

Class MainWindow 

    Class person 

     Property name 
     Property age 

    End Class 

    Dim listOfPersons As New List(Of person) 
    Private filteredList As CollectionViewSource 
    Dim view As ICollectionView 

    Private Sub DataGrid_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) 

    End Sub 

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

     Dim aPerson As New person With { 
      .name = "Fred Smith", 
      .age = 12} 

     listOfPersons.Add(aPerson) 

     Dim bPerson As New person With { 
     .name = "Tom Jones", 
     .age = 50} 

     listOfPersons.Add(bPerson) 

     view = CollectionViewSource.GetDefaultView(listOfPersons) 
     displayGrid.ItemsSource = view 

    End Sub 


    Function ShowOnlyChildrenFilter(ByVal param As Object) As Boolean 
     Dim person As person = TryCast(param, person) 
     Dim retValue As Boolean 

     If person IsNot Nothing Then 
      ' Filter out persons with age less than 18 
      If person.age < 19 Then 
       retValue = True 
      Else 
       retValue = False 
      End If 
     End If 

     Return retValue 

    End Function 

    Private Sub showOnlyChildren_Checked(sender As Object, e As RoutedEventArgs) Handles showOnlyChildren.Checked 

     If showOnlyChildren.IsChecked = True Then 
      view.Filter = New Predicate(Of Object)(AddressOf ShowOnlyChildrenFilter) 
     Else 
      'what goes here? 
     End If 

    End Sub 
End Class 

我唯一缺少的是如何刷新数据网格,当复选框未选中时。谢谢大家。我仍然很惊讶这是多么复杂和大胆的想法,因为我认为这很简单。

+0

什么线给你的错误? – Steve

+0

@Steve AddHandler filteredList.Filter,AddressOf ShowOnlyChildrenFilter,当我点击复选框。我在CollectionViewSource前添加了New关键字,现在不会出现错误。只是不做我想要的。 – bendecko

+0

我没有看到你在发布的代码中引用的行? – Steve

回答

0

OK完成。在上面的代码中出现了更多的新手错误。所以这里是工作版本。勾选一个复选框,它会过滤条件。

VB代码:

Imports System.ComponentModel 

Class MainWindow 

    Class person 

     Property name 
     Property age 

    End Class 

    Dim listOfPersons As New List(Of person) 
    Dim view As ICollectionView 

    Private Sub DataGrid_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) 
     MsgBox("changed") 
    End Sub 

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

     Dim aPerson As New person With { 
      .name = "Fred Smith", 
      .age = 12} 

     listOfPersons.Add(aPerson) 

     Dim bPerson As New person With { 
     .name = "Tom Jones", 
     .age = 50} 

     listOfPersons.Add(bPerson) 

     view = CollectionViewSource.GetDefaultView(listOfPersons) 
     displayGrid.ItemsSource = view 

    End Sub 


    Function ShowOnlyChildrenFilter(ByVal param As Object) As Boolean 
     Dim person As person = TryCast(param, person) 
     Dim retValue As Boolean 

     If person IsNot Nothing Then 
      ' Filter out persons with age less than 18 
      If person.age < 19 Then 
       retValue = True 
      Else 
       retValue = False 
      End If 
     End If 

     Return retValue 

    End Function 

    Private Sub showOnlyChildren_Checked(sender As Object, e As RoutedEventArgs) Handles showOnlyChildren.Checked 

     If showOnlyChildren.IsChecked = True Then 
      view.Filter = New Predicate(Of Object)(AddressOf ShowOnlyChildrenFilter) 
     End If 


    End Sub 

    Private Sub showOnlyChildren_UnChecked(sender As Object, e As RoutedEventArgs) Handles showOnlyChildren.Unchecked 

     If showOnlyChildren.IsChecked = False Then 
      view.Filter = Nothing 
     End If 

    End Sub 
End Class 

使用XAML:

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 

    <Grid> 
     <DataGrid x:Name="displayGrid" HorizontalAlignment="Left" Margin="62,94,0,0" VerticalAlignment="Top" Height="142" Width="360" SelectionChanged="DataGrid_SelectionChanged"/> 
     <Button Content="Load" HorizontalAlignment="Left" Margin="62,51,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/> 
     <CheckBox x:Name="showOnlyChildren" Content="Show Only Children" HorizontalAlignment="Left" Margin="172,51,0,0" VerticalAlignment="Top" Width="147"/> 

    </Grid> 
</Window> 
2

这应该是一个评论,而不是一个答案,但我无法评论为不够的代表!

您是否尝试过使用

ICollectionView

我有一个C#例如,如果你能够将它转换我可以提供!

编辑:

我想我只是在例如盘,因为它可能有点帮助

private void cbBlahYear_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     lvwMainBlahFilter(); 
    } 

    private void lvwMainBlahFilter() 
    { 
     ICollectionView view = CollectionViewSource.GetDefaultView(lvwMainBlah.ItemsSource); 

     view.Filter = null; 
     view.Filter = new Predicate<object>(FilterBlahByYearID); 
     view.SortDescriptions.Add(new SortDescription("Forename", ListSortDirection.Ascending)); 
    } 

    private Boolean FilterBlahByYearID(object obj) 
    { 
     BlahModel item = obj as BlahModel; 
     if (item == null) return false; 

     Int32 myID = 0; 
     if (cbBlahYear.SelectedItem != null) 
     { 
      YearModel year = cbBlahYear.SelectedItem as YearModel; 
      myID = year.id; 
     } 

     if (myID == 0) return false; 

     if (item.YearID == myID) return true; 
     return false; 
    } 
+0

看起来很有趣。你是否有其余的部分,比如类定义和dataloader,还有XAML?有很少的VB.net我可能不得不迁移...所有这些curl大括号是可怕的tho :) – bendecko

+0

以及cb是一个组合框。 lvw是一个listview,FilterbyBlah只是一个函数。改变语法,你应该在那里。 –

+0

对不起,我是一个完整的新手在这里。这里是我的课程: 'class BlahModel { public object Forename {get;组; } 公共对象YearID {get;组; } }' – bendecko

0

变量filteredList您特林:

AddHandler filteredList.Filter, AddressOf ShowOnlyChildrenFilter 

依然是这条线没有任何东西。尝试首先声明它为NEW:

Private filteredList As New CollectionV 
+0

它已经停止了抛出错误,但它不会过滤。 – bendecko

+0

我把一个断点放在 Dim person As person = TryCast(e.Item,person) line,它从来没有击中过它。那是因为功能通过了吗? – bendecko

+0

不,不对。它需要击中它。帮帮我。 – bendecko