簡體   English   中英

LINQ:動態Where子句,用於切換案例組合

[英]LINQ: dynamic Where clause with toggle the combination of cases

我有一個綁定到angridview的列表,我希望能夠“動態”創建過濾器Where子句,同時由用戶控制過濾器選項的組合。

按模型布爾屬性過濾原始列表的最佳方法是什么,並允許切換過濾器的每個條件?

我知道filterdList不是nececery,但我已經看過的其他解決方案都不允許切換Where子句的條件。

public partial class Form1 : Form
{
    List<dummy> Origlist = new List<dummy> {
        new dummy { pk = 1 ,  istype1 = true,  istype2  = false, istype3=false, istype4=false },
        new dummy { pk = 2 ,  istype1 = true,  istype2 = false,  istype3=false, istype4=false },
        new dummy { pk = 3 ,  istype1 = false, istype2 = true,   istype3=false, istype4=false },
        new dummy { pk = 4 ,  istype1 = false, istype2 = true,   istype3=false, istype4=false },
        new dummy { pk = 5 ,  istype1 = false, istype2 = false,  istype3=true,  istype4=false },
        new dummy { pk = 6 ,  istype1 = false, istype2 = false,  istype3=true,  istype4=false },
        new dummy { pk = 7 ,  istype1 = false, istype2 = false,  istype3=false, istype4=true },
        new dummy { pk = 8 ,  istype1 = false, istype2 = false,  istype3=false, istype4=true },
        new dummy { pk = 9 ,  istype1 = false, istype2 = false,  istype3=true,  istype4=false },
        new dummy { pk = 10 , istype1 = false, istype2 = true,   istype3=false, istype4=false },
        new dummy { pk = 11 , istype1 = false, istype2 = false,  istype3=false, istype4=false }
        };
    List<dummy> filteredList = new List<dummy>(); 
    public Form1()
    {
        InitializeComponent();
    }

    private void Bind()
    {
        dataGridView1.DataSource = null;
        dataGridView1.DataSource = filteredList;
    }


    private void checkBox1_CheckedChanged(object sender, EventArgs e)
    {
        if (checkBox1.Checked)
        {
            filteredList.AddRange(Origlist.Where(a => a.istype1 == true).ToList());
        }
        else
        {
            filteredList.RemoveAll(a => a.istype1 == true);
        }
        Bind();
    }



    private void checkBox2_CheckedChanged(object sender, EventArgs e)
    {
        if (checkBox2.Checked)
        {
            filteredList.AddRange(Origlist.Where(a => a.istype2 == true).ToList());
        }
        else
        {
            filteredList.RemoveAll(a => a.istype2 == true);
        }
        Bind();
    }

    private void checkBox3_CheckedChanged(object sender, EventArgs e)
    {
        if (checkBox3.Checked)
        {
            filteredList.AddRange(Origlist.Where(a => a.istype3 == true).ToList());
        }
        else
        {
            filteredList.RemoveAll(a => a.istype3 == true);
        }
        Bind();
    }

    private void checkBox4_CheckedChanged(object sender, EventArgs e)
    {
        if (checkBox4.Checked)
        {
            filteredList.AddRange(Origlist.Where(a => a.istype4 == true).ToList());
        }
        else
        {
            filteredList.RemoveAll(a => a.istype4 == true);
        }
        Bind();
    }

}

模擬

嘗試這樣的事情(未經測試):

public partial class Form1 : Form
{
    List<dummy> Origlist = new List<dummy> {
        new dummy { pk = 1 ,  istype1 = true,  istype2  = false, istype3=false, istype4=false },
        new dummy { pk = 2 ,  istype1 = true,  istype2 = false,  istype3=false, istype4=false },
        new dummy { pk = 3 ,  istype1 = false, istype2 = true,   istype3=false, istype4=false },
        new dummy { pk = 4 ,  istype1 = false, istype2 = true,   istype3=false, istype4=false },
        new dummy { pk = 5 ,  istype1 = false, istype2 = false,  istype3=true,  istype4=false },
        new dummy { pk = 6 ,  istype1 = false, istype2 = false,  istype3=true,  istype4=false },
        new dummy { pk = 7 ,  istype1 = false, istype2 = false,  istype3=false, istype4=true },
        new dummy { pk = 8 ,  istype1 = false, istype2 = false,  istype3=false, istype4=true },
        new dummy { pk = 9 ,  istype1 = false, istype2 = false,  istype3=true,  istype4=false },
        new dummy { pk = 10 , istype1 = false, istype2 = true,   istype3=false, istype4=false },
        new dummy { pk = 11 , istype1 = false, istype2 = false,  istype3=false, istype4=false }
    };

    Options options = new Options();

    private class Options {
        public bool istype1 { get; set; }
        public bool istype2 { get; set; }
        public bool istype3 { get; set; }
        public bool istype4 { get; set; }
    }

    public Form1()
    {
        InitializeComponent();
    }

    private void Bind()
    {
        dataGridView1.DataSource = null;
        dataGridView1.DataSource = OrigList.Where(a =>
          (options.istype1 && a.istype1) ||
          (options.istype2 && a.istype2) ||
          (options.istype3 && a.istype3) ||
          (options.istype4 && a.istype4)
        ).ToList();
    }


    private void checkBox1_CheckedChanged(object sender, EventArgs e)
    {
        options.istype1 = checkBox1.checked;
        Bind();
    }



    private void checkBox2_CheckedChanged(object sender, EventArgs e)
    {
        options.istype2 = checkBox2.checked;
        Bind();
    }

    private void checkBox3_CheckedChanged(object sender, EventArgs e)
    {
        options.istype3 = checkBox3.checked;
        Bind();
    }

    private void checkBox4_CheckedChanged(object sender, EventArgs e)
    {
        options.istype4 = checkBox4.checked;
        Bind();
    }

}

還有其他方法可以減少重復,但這是一個開始。

我想說最簡單/最干凈的方法是使用ADO.NET DataSet來處理你的數據,而不是使用一堆帶有一些Linq查詢的List。 ADO.NET DataSet是官方的Winforms生活方式

您可以將這些數據集/數據表與BindingSource組件一起用作DataGridView的DataSource,並使用BindingSource的Filter String屬性。 這個String表達式可以通過一些If子句輕松構建,這些子句按照MSND DataColumn表達式語法測試CheckBox的狀態和字符串連接。

還有一些其他干凈的方法,比如使用IBindingListView接口的部分實現來擴展BindingList類。 但這是一些相當困難的東西,特別是當你知道微軟已經為你為DataSet做了這項工作時...如果你不害怕,這篇文章是一個很好的起點。

可以為每個CheckBox重用單個事件處理程序,並且該事件處理程序可以將每個屬性與相應的CheckBox進行比較。

List<dummy> Origlist = new List<dummy> 
{
    new dummy { pk = 1 ,  istype1 = true,  istype2 = false,  istype3=false, istype4=false },
    new dummy { pk = 2 ,  istype1 = true,  istype2 = false,  istype3=false, istype4=false },
    new dummy { pk = 3 ,  istype1 = false, istype2 = true,   istype3=false, istype4=false },
    new dummy { pk = 4 ,  istype1 = false, istype2 = true,   istype3=false, istype4=false },
    new dummy { pk = 5 ,  istype1 = false, istype2 = false,  istype3=true,  istype4=false },
    new dummy { pk = 6 ,  istype1 = false, istype2 = false,  istype3=true,  istype4=false },
    new dummy { pk = 7 ,  istype1 = false, istype2 = false,  istype3=false, istype4=true  },
    new dummy { pk = 8 ,  istype1 = false, istype2 = false,  istype3=false, istype4=true  },
    new dummy { pk = 9 ,  istype1 = false, istype2 = false,  istype3=true,  istype4=false },
    new dummy { pk = 10 , istype1 = false, istype2 = true,   istype3=false, istype4=false },
    new dummy { pk = 11 , istype1 = false, istype2 = false,  istype3=false, istype4=false }
};

public Form1()
{
    InitializeComponent();
}

private void checkBox_CheckedChanged(object sender, EventArgs e)
{
     dataGridView1.DataSource = Origlist.Where(a => 
         a.istype1 == checkBox1.Checked && 
         a.istype2 == checkBox2.Checked && 
         a.istype3 == checkBox3.Checked && 
         a.istype4 == checkBox4.Checked).ToList();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM