繁体   English   中英

从实体框架过滤绑定到ViewSource的DataGrid

[英]Filtering DataGrid bound to ViewSource from Entity Framework

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

为简单起见,我有一个数据库优先应用程序。 我想显示怪物表中的怪物列表,然后根据名称进行过滤。 在winforms中,我可以执行此操作,但是WPF中的Datagrids似乎使我陷入循环

XAML:

<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>

C#:

public partial class MainWindow : Window
    {
        adventuretime adventuretime;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {

            adventuretime = ((adventuretime)(this.FindResource("adventuretime")));

            // Load data into the table Monsters. You can modify this code as needed.
            adventuretimeTableAdapters.MonstersTableAdapter adventuretimeMonstersTableAdapter = new adventuretimeTableAdapters.MonstersTableAdapter();
            adventuretimeMonstersTableAdapter.Fill(adventuretime.Monsters);
            CollectionViewSource monstersViewSource = ((CollectionViewSource)(this.FindResource("monstersViewSource")));
            monstersViewSource.View.MoveCurrentToFirst();
        }
    }

应用程序加载,并且我从表中获取数据,所以很棒。

我只是不知道如何操作其中的数据。

做类似dataGrid.ItemSource = linq查询的事情似乎不是一个选择。 所以我不确定如何绑定它,所以我可以过滤文本框内容。

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

在此处输入图片说明

CollectionViewSource.View具有一个Predicate <object>的Filter属性。 用它来过滤。

要将其绑定到您的文本框中,假设您想对“名称”进行过滤,请将事件处理程序添加到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;
        };
    }
}

筛选器使用包含而不是等于,因此它将筛选出所有不包含文本框文本的内容。 像“ dra”将匹配“ dragon”和“ drake”。

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

编辑:

我猜DataTable不支持那样的筛选。 您可能需要将DataSet1更改为您的DataSet。 也许在LIKE语句中占*的%?

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方法来代替数据集,数据适配器和数据表,以使其能够更快地进行过滤。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM