如何从对象ListBox中正确检索数据并使用带有Lambda表达式的ComboBox对其进行过滤?

时间:2018-04-24 07:08:53

标签: c# .net winforms lambda listbox

我正在开发一个Windows窗体项目,其中有一个名为 Client 的类,它有自己的属性和静态列表。我还有一个表格,你注册新的客户,我101%肯定是正确的,所以我不会在这里发布它的代码。每次注册客户端时,都会将其添加到静态列表中。

问题出在我为上市客户提供的表格中。此表单有一个 ListBox ,可以显示已注册客户的所有 ID ' Check Button' 用于显示所选客户端的所有信息(列表框中的选定ID),旁边有一组标签。 在所有提到的内容中,我有一个 ComboBox ,它有两个选项:男性女性。这个ComboBox用于过滤仅属于所选性别的ID。

List Clients Form IMAGE

我在列出和过滤客户端时遇到了很多问题:

1-当我尝试将所有已注册的客户端添加到ListBox时,我遇到了第一个问题,我首先尝试使用不同的 Lambda表达式(如下所示:Lista.Items.Add(Client.clients) .Find(i => i.Id == i.Id).Id)但是我无法做到这一点,它部分地使用了一个表达式,它一遍又一遍地用相同的ID填充ListBox。然后研究了很多并阅读了很多不同的问题我使用了ListBox的 DataSource 属性来将客户列表与我的ListBox绑定,但是我不得不改变这种做法,因为我在过滤数据(更新数据源)时,我无法按照我的意愿更新 ListBox。

所以之后我更改了它并使用了 foreach循环来填充ListBox。

当我使用DataSource来填充ListBox而不是foreach时,我在检查客户端的信息并在表单中显示时没有任何问题,但是当我使用foreach循环来填充ListBox(两种方法都应该以我猜的方式填充ListBox)我不能使用相同的方法显示客户端的信息(在private void button1_Click(object sender, EventArgs e)方法中),我得到一个"对象参考未设置为对象的实例"错误。为什么会这样?我该如何解决这个问题?

2-另一个大问题是在过滤ID时,如下面的代码所示,我尝试使用datasource属性填充ListBox,并使用带有过滤ID的foreach,但我无法设法执行Lambda表达式过滤ID,也不从列表中填充或删除对象。

在这种情况下填写列表的最佳方法是什么?如果我想使用Lambda表达式用List静态列表中注册的ID填充ListBox,这会导致我在组合框中过滤ID时出现问题应该如何? (我只是想了解这一点)。

请阅读代码及其评论以了解更多信息。

请同时查看图片

class Client
{
    private string id; 
    private string name;
    private byte idSex; // 1= Male    2= Female

    public string Name
    {
        get {return name; }
        set {this.name= value; }
    }

    public string Id
    {
        get { return this.id; }
        set { this.id= value; }
    }

    public byte IdSex
    {
        get { return this.idSex; }
        set { this.idSex = value; }
    }


    public static List<Client> clients = new List<Client>(); //Clients are added here

    public Client(string id, string name, byte idSex)
    {
        this.id=id;
        this.name=name;
        this.idSex=idSex;
    }
}


public partial class ListadoClientes : Form //ignore the name, I translated everything to English because I speak Spanish
{
    public ListadoClientes()
    {
        InitializeComponent();

        List<string> sexos = new List<string>(){ "Male", "Female" };

        Lista.Items.Clear();//NOTE: 'Lista' is the name of the ListBox*****

        /*Lista.DataSource = Client.clients; commented because I couldn't update the listbox when I wanted to filter the data and fill the listbox again but with IDs of only one sex*/


        foreach(Client c in Client.clients)
        {
            Lista.Items.Add(c);
        }
        Lista.DisplayMember = "Id";
        Lista.ValueMember = "Id";

        foreach(string s in sexos)//adding the gender to the combobox
        {

            ComboSexo.Items.Add(s); //ComboSexo is the name of the Combobox

            /* string y = Lista.GetItemText(Lista.TopIndex+1);
                Lista.Items.Add(Client.clients.Find(i => i.Id!= y).Id); >>>>HERE I TRIED TO USE A LAMBDA EXPRESSION, USED OTHERS TOO*/
        }
    }

    private void ListadoClientes_Load(object sender, EventArgs e)
    {
        //not used
    }

    private void Lista_SelectedIndexChanged(object sender, EventArgs e)
    {
        //not used       
    }

    private void button1_Click(object sender, EventArgs e)
    {
        //THIS CODE WORKS FOR DISPLAYING INFO IN THE LABELS WHEN USING THE DATASOURCE PROPERTY FOR FILLING THE LISTBOX BUT IT DOESN'T WORK WITH THE FOREACH WAY.
        string sex;// 1= Male 2= Female


        //code below to save the sex of the client to a string value depending on its id
        if (Cliente.clientes.Find(i => Lista.SelectedValue == i.Id).IdSex == 1)
        {
            sex = "Male";
        }
        else
        {
            sex = "Female";
        }

        LblId.Text = Client.clients.Find(i => Lista.SelectedValue == i.Id).Id;
        LblName.Text = Client.clients.Find(i => Lista.SelectedValue == i.Id).Name;
        LblSex.Text = sex;
    }

    private void ComboSexo_SelectedIndexChanged(object sender, EventArgs e)
    {

    }

    private void BtnFiltrarSexo_Click(object sender, EventArgs e)
    {

        if (ComboSexo.Text == "Male")
        {

            /*Lista.Items.Clear();
                Lista.DataSource = Client.clients.Find(i=> i.IdSex==2);
                Lista.DisplayMember = "Id";
                Lista.ValueMember = "Id";
                Tried to do this at first when I had the listbox filled with the DataSource*/


            /*int y=Client.clients.Count;
                for(int i=0; i<y;i++)
                {
                    if ()
                    {
                        Lista.Items.Remove(c);
                >>>did not work<<<

                }*/
            /*Lista.Items.Remove(Client.clients.Find(i=> i.IdSex!=1 )); I also tried to Remove using a Lambda Expression but this worked only removing 1 Client!! then I tried using a for loop or a foreach but I couldn't do it.

            }
            else if(ComboSexo.SelectedText == "Female")
            {
                Lista.Items.Clear();
                Lista.DataSource = Client.clients.Find(i=> i.IdSex==2);
                Lista.DisplayMember = "Id";
                Lista.ValueMember = "Id";
                //this won't work also
            }
            else
            {
                MessageBox.Show("Error you must select a sex");
            }*/
        }
    }
}

PS:列表中的ID显示如下:123,345,864等等,所以如果按性别过滤,请说只有id 345是男性,然后点击&#39 ;过滤按钮&#39;列表框将仅显示id 345。

1 个答案:

答案 0 :(得分:0)

填写所有客户

        Lista.Items.Clear();
        Lista.Items.AddRange(Client.clients.ToArray());

仅填充男性

        Lista.Items.Clear();
        Lista.Items.AddRange(Client.clients.Where(x => x.IdSex == 1).Select(x => x).ToArray());

仅填写女性

        Lista.Items.Clear();
        Lista.Items.AddRange(Client.clients.Where(x => x.IdSex == 2).Select(x => x).ToArray());