我似乎遇到了使用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设计器时似乎与我的应用程序生成的内容不匹配
答案 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方法而不是数据集,数据适配器和数据表来使其更快地过滤。