动态和通用搜索数据源中的特定对象

时间:2012-09-18 17:38:09

标签: c# winforms linq generics entity-framework-4

我有一个使用Entity Framework和LINQ的Windows窗体应用程序 有很多形式,我使用BindingNavigator来导航数据,我想在导航器中添加一个textBox来搜索特定的项目并导航到它,我做了一个,但现在我必须做同样的步骤对于其他表单,并在每个表单中添加相同的事件和代码,所以我决定制作一个自定义ToolStripTextBox,我在每个表单中使用它,但我必须使它通用,因为每个表单使用不同的对象或实体,这是什么我想出来:

class ToolStripSearchBox<T> : ToolStripTextBox
{
    BindingSource dataSource;
    int currentIndex;

    public ToolStripSearchBox()
        : base()
    {
        KeyUp += new KeyEventHandler(ToolStripSearchBox_KeyUp);
    }

    void ToolStripSearchBox_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.F4)
        {
            string patern = Text;
            List<T> TList = dataSource.List.Cast<T>().ToList();
            int res = 0;
            T foundT = default(T);

            if (int.TryParse(patern, out res))
            {
                foundT = TList.Where(j => j. == res).First();

            }
            else
            {
                foundT = TList.First(j => (j.FirstName + " " + j.LastName).Contains(patern));
            }
            if (foundT == null)
            {
                return;
            }

            dataSource.Position = dataSource.IndexOf(foundT);
        }
    }
}

但问题是每个实体都有不同的属性要过滤,我想使用字符串参数来传递对象属性名称,但我没有找到一种方法将它与LINQ一起使用。

对不起,如果有听写错误,但英语不是我的第一语言 提前致谢

1 个答案:

答案 0 :(得分:1)

对于我在您的代码中看到的内容,“每个实体都有不同的属性可以过滤”,您指的是FirstNameLastName等属性。

如果是这种情况,很简单,您可以定义一个通用函数对象来用作匹配器。您可以在构造时或初始化期间指定此项。 (我不太喜欢没有参数构造函数的组件。)

class ToolStripSearchBox<T> {
    public Func<T, string, bool> Matcher { get; set; }
}

例如,在初始化其中一个用于搜索Foo的框时,您会这样做:

ToolStripSearchBox<Foo> fooSearchBox = new ToolStripSearchBox<Foo>();
fooSearchBox.Matcher = (j, pattern) => (j.Second + " " + j.Second).Contains(pattern);

也就是说,你的代码存在很多问题:请记住,如果没有找到任何元素,First()扩展方法将抛出异常;使用FirstOrDefault()。我看到你也在使用foundT == null ..我怀疑这甚至会编译。请改为foundT == default(T)

class ToolStripSearchBox<T> {

    void ToolStripSearchBox_KeyUp(object sender, KeyEventArgs e)
    {
        ...
            foundT = TList.FirstOrDefault(this.Matcher(j, patern));
        ...
    }
}