从Entity Framework过滤绑定到ViewSource的DataGrid

时间:2016-06-10 16:50:28

标签: c# wpf entity-framework xaml datagrid

我似乎遇到了使用WPF和Entity Framework绑定到数据网格的问题。

为简单起见,我有一个数据库第一个应用程序。我想显示怪物表中的怪物列表,然后根据名称进行过滤。在winforms中,我可以做到这一点,但WPF中的Datagrids似乎让我完成了循环

XAML:

<tr class="ligne" style="height: 0px; background-color: white;">
    <td style="border-bottom: black 1px solid; padding-bottom: 0px; height: 1px; padding-top: 0px;" colSpan="6"/>
</tr>

C#:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication2"
        mc:Ignorable="d"
        Title="MainWindow" Height="500" Width="1000" Loaded="Window_Loaded">
    <Window.Resources>
        <local:adventuretime x:Key="adventuretime"/>
        <CollectionViewSource x:Key="monstersViewSource" Source="{Binding Monsters, Source={StaticResource adventuretime}}"/>
    </Window.Resources>
    <Grid DataContext="{StaticResource monstersViewSource}">
        <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="22" Margin="10,10,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="972"/>
        <DataGrid x:Name="monstersDataGrid" AutoGenerateColumns="False" EnableRowVirtualization="True" ItemsSource="{Binding}" Margin="10,37,10,10" RowDetailsVisibilityMode="VisibleWhenSelected">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="monsterIDColumn" Binding="{Binding MonsterID}" Header="Monster ID" IsReadOnly="True" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="nameColumn" Binding="{Binding Name}" Header="Name" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="sizeColumn" Binding="{Binding Size}" Header="Size" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="monstertypeColumn" Binding="{Binding Monstertype}" Header="Monstertype" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="alignmentColumn" Binding="{Binding Alignment}" Header="Alignment" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="aCColumn" Binding="{Binding AC}" Header="AC" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="hPColumn" Binding="{Binding HP}" Header="HP" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="strengthColumn" Binding="{Binding Strength}" Header="Strength" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="dexterityColumn" Binding="{Binding Dexterity}" Header="Dexterity" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="constitutionColumn" Binding="{Binding Constitution}" Header="Constitution" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="intelligenceColumn" Binding="{Binding Intelligence}" Header="Intelligence" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="wisdomColumn" Binding="{Binding Wisdom}" Header="Wisdom" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="charismaColumn" Binding="{Binding Charisma}" Header="Charisma" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="savesColumn" Binding="{Binding Saves}" Header="Saves" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="skillColumn" Binding="{Binding Skill}" Header="Skill" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="immuneColumn" Binding="{Binding Immune}" Header="Immune" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="sensesColumn" Binding="{Binding Senses}" Header="Senses" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="languagesColumn" Binding="{Binding Languages}" Header="Languages" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="passiveColumn" Binding="{Binding Passive}" Header="Passive" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="speedColumn" Binding="{Binding Speed}" Header="Speed" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="crColumn" Binding="{Binding cr}" Header="cr" Width="SizeToHeader"/>
            </DataGrid.Columns>
        </DataGrid>

    </Grid>
</Window>

应用程序加载,我从表中获取数据,这很好。

我根本不知道如何操纵那里的数据。

执行类似dataGrid.ItemSource = linq查询的操作似乎不是一个选项。所以我不确定如何绑定它所以我可以过滤文本框内容。

有人能指出我正确的方向吗?我一直在寻找最近两天但是当我将数据网格拖放到WPF设计器时似乎与我的应用程序生成的内容不匹配

enter image description here

1 个答案:

答案 0 :(得分:1)

CollectionViewSource.View有一个Filter属性,它是Predicate&lt; object&gt;。用它来过滤。

要将其绑定到文本框中,假设您要对&#39; Name&#39;进行过滤,请在TextChanged事件的文本框中添加事件处理程序。像这样:

<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="22" Margin="10,10,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="972"
    TextChanged="TextBox_TextChanged" />

在后面的代码中,添加TextBox_TextChanged方法。将其定义为:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    var tb = sender as TextBox;
    CollectionViewSource monstersViewSource = ((CollectionViewSource)(this.FindResource("monstersViewSource")));

    if (tb == null || string.IsNullOrWhiteSpace(tb.Text))
    {
        monstersViewSource.View.Filter = null;
        return;
    }
    else
    {
        string txt = tb.Text;
        monstersViewSource.View.Filter = item =>
        {
            Monster m = item as Monster;
            if (m != null)
            {
                if (!string.IsNullOrWhiteSpace(m.Name) && m.Name.Contains(txt))
                    return true;
            }
            return false;
        };
    }
}

过滤器使用Contains而不是equals,因此它会过滤掉任何不包含文本框文本的内容。喜欢&#34; dra&#34;将匹配&#34;龙&#34;和&#34;德雷克&#34;。

顺便说一句 - 我在这个问题上没有看到任何实体框架。

修改

我猜DataTable并不支持这样的过滤......请尝试这样做。您可能需要将DataSet1更改为您的DataSet。也许LIKE语句中的%to *?

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    var tb = sender as TextBox;
    CollectionViewSource monstersViewSource = ((CollectionViewSource)(this.FindResource("monstersViewSource")));

    if (tb == null || string.IsNullOrWhiteSpace(tb.Text))
    {
        DataSet1.MonstersDataTable dt = monstersViewSource.Source as DataSet1.MonstersDataTable;
        dt.DefaultView.RowFilter = null;
        return;
    }
    else
    {
        string txt = tb.Text;

        DataSet1.MonstersDataTable dt = monstersViewSource.Source as DataSet1.MonstersDataTable;
        dt.DefaultView.RowFilter = string.Format("Name LIKE '%{0}%'", txt);
    }
}

编辑2:

这会更快吗?

private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    var tb = sender as TextBox;
    CollectionViewSource monstersViewSource = ((CollectionViewSource)(this.FindResource("monstersViewSource")));

    if (tb == null || string.IsNullOrWhiteSpace(tb.Text))
    {
        var cv = monstersViewSource.View as BindingListCollectionView;
        cv.CustomFilter = null;
    }
    else
    {
        string txt = tb.Text;

        var cv = monstersViewSource.View as BindingListCollectionView;
        cv.CustomFilter = string.Format("Name like '%{0}%'", txt);
    }
}

如果不是更快,我认为您可能需要实际使用实体框架和第一个TextBox_TextChanged方法而不是数据集,数据适配器和数据表来使其更快地过滤。