1

WPF/VB.net 新手在这里。

我正在尝试过滤数据网格中的行并玩得很开心。

我设法创建了一个对象列表并使用 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

编辑:好的,但肯定会到达那里。我合并了我在此处找到的一些更改,并感谢我来到这里的帮助......这就是代码现在的样子:

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

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

4

3 回答 3

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;
    }
于 2013-10-18T11:25:41.783 回答
0

您要尝试的变量filteredList

AddHandler filteredList.Filter, AddressOf ShowOnlyChildrenFilter

在这条线上还是什么都没有。尝试先将其声明为 NEW:

Private filteredList As New CollectionV
于 2013-10-18T18:42:58.733 回答
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>
于 2013-10-21T07:57:44.027 回答