动态LINQ过滤器永远不会检索正确的结果(UWP / XAML)

时间:2017-09-01 05:32:19

标签: c# linq xaml uwp

我的班级是ObservableCollection<Miniature>MiniList

public class Miniature
{
    public string Name { get; set; }
    public int Quantity { get; set; }
    public string Image { get; set; }
    public string Manufacturer { get; set; }
    public string Set { get; set; }
    public string Location { get; set; }
}

这些属性的名称被输入到ComboBox中,用户可以在其中选择一个(或选择ALL)并键入搜索词以对列表进行排序。  继承了xaml的价值:

 <TextBlock Text="Search"
                       Style="{StaticResource RPTextBlock}"/>
            <ComboBox Name="FilterComboBox"
                      ItemsSource="{x:Bind FilterComboList}"                      
                      Style="{StaticResource RPCombo}"
                      FlowDirection="RightToLeft"  
                      SelectionChanged="FilterComboBox_SelectionChanged"
                      Loaded="comboBox_Loaded"/>
            <TextBlock Text="For"
                       Style="{StaticResource RPTextBlock}"/>
            <TextBox Name="SearchTextBox"
                     PlaceholderText="Search Term"/>
            <Button Content="&#xE094;"
                    Name="SearchIcon"                        
                    Style="{StaticResource RPButton}"
                    FontFamily="Segoe MDL2 Assets"
                    FontSize="20"     
                    Click="SearchIcon_Click"/>

最初我的问题是:当我提前知道将选择哪个属性时,如何做MiniList.AsQueryable().Where(m=>m.Property ==SearchTextBox.Text)。在做了研究之后,动态linq似乎还有很长的路要走(尽管我对任何解决方案持开放态度)。为此,我有这个事件:

private void SearchIcon_Click(object sender, RoutedEventArgs e)
{
    FilterGridView(SearchTextBox.Text);
    SearchTextBox.Text = "";
}

调用此方法:

private void FilterGridView(string submission)
{
    var selected = FilterComboBox.SelectedValue;
    MVM = new MiniViewModel();//This is specific for passing a pregenerated list of minis, later might load from disk or db                            

    var templist = MVM.MiniCollection.AsQueryable()
        .Where("@0 = @1", selected, submission);
    MiniList.Clear();
    templist.ToList<Miniature>()
        .ForEach(m => MiniList.Add(m));
}

即使使用最基本的示例,也不会产生任何结果,尝试使用string或int属性。选择和提交正确显示,如果我在组合框中选择名称并输入“Succubus”,则tempList的值显示为

templist    {System.Collections.Generic.List`1[UWPMiniatures.Models.Miniature].Where(Param_0 => ("Name" == "Succubus"))}    System.Linq.IQueryable<UWPMiniatures.Models.Miniature> {System.Linq.EnumerableQuery<UWPMiniatures.Models.Miniature>}

它确实清除了我的项目出现的网格。在结果视图下调试和单步执行tempList,总是说“{Empty”Enumeration没有产生任何结果“

我在一个简单的控制台程序上尝试过这个设置并且无法让它工作,尽管这与我见过的例子很相似,所以我不确定我做错了什么或者是否还有另一个这样做的方法。

编辑 - 我不知道如何解释它。让我试着填补一些空白。我在xaml中有一个gridview,其源是ObservableCollection<Miniature>MiniList。现在,使用测试值初始化源。我希望能够通过输入搜索词并从组合框中选择一个属性值来筛选列表,这样如果我在搜索框中选择属性Quantity并输入2,则显示在gridview所有项目的数量== 2.正如我所说,尝试动态扩展到linq不起作用

1 个答案:

答案 0 :(得分:1)

动态LINQ中的@0@1等是常量值占位符。因此

.Where("@0 = @1", selected, submission);

生成无意义字符串比较

"Name" == "Succubus"

所以你没有得到正确的结果就不足为奇了。

您真正需要的是将属性名称嵌入谓词字符串中,并仅使用占位符作为值。

假设selected变量包含属性名称,则用法应如下所示:

.Where(selected + " = @0", submission);

或使用C#6 interpolated string

.Where($"{selected} = @0", submission);