winforms 如何在C# Windows窗体中编写指向dataGridView的LINQ

kmpatx3s  于 2022-12-04  发布在  C#
关注(0)|答案(1)|浏览(189)

I've got stuck with developing a LINQ search in dataGridView . On the form I dragged button , bindingSourcedataGridView and comboBox . When I started programming button I've catched the unlogical action from C#. When I write else if block then button doesn't work, if I write else block, it works. How is it possible
Seacrhing criterias:
-The most expensive item in the list
-The cheapest item in the list

  • Item which presents in collection

I've connected bindingSource to the dataGridView object
Here is a code:

public partial class Form1: Form 
{
     public List<ProductClass> Product {get; set;}
     public Form1()
     {
          InitializeComponent();
          Product = new List<ProductClass>
          {
             new Product("BigMac", 300.0, 4000, "In collection"),
             //....... there is 19 more objects 
          };
          productBindingSource.DataSource = Product;
     }
}
private void SearchButton_Click(object sender, EventArgs e)
{
       if(comboBox1.SelectedItem.ToString() == "The cheapest item")
       {
           var query = Product.OrderBy(x=>x.Price);
           var minimum = query.First(); // Taking the first element from the list 
           productBindingSource.DataSource = minimum;
       }
       // This else if block is ignored, instead of it works block else 
       else if(comboBox1.SelectedItem.ToString() == "The most expensive item)
       {
           var query = Product.OrderBy(x=>x.Price);
           var maximum = query.Last(); // taking the last element from the list 
           productBindingSource.DataSource = maximum;
       }
       // This block works when I choose from comboBox or Item in Collection or The most expensive item criteria 
      else 
      {
           var query = from pr in Product where pr.CollectionStatus == "In collection" select pr;
          productBindingSource.DataSource = query;
      }
}

I can't find out what is wrong here :(
Also when I wrote something like that:

else 
{
     if(//....)
     {
         //....
     }
     else
     {
        //....
     }
}

It crashes me all so the LINQ doesnt work completely :(
Any help with the code template is appreciated. Thanks in advance

mi7gmzs6

mi7gmzs61#

一个很大的问题是,您查询DataSource,然后将DataSource设置为查询productBindingSource.DataSource = minimum的结果。第一个查询有20个产品(您说),但接下来呢?查询返回最小(或最大)产品,然后DataSource下次只有一个产品可供选择,而不是20个。
您的计划可以让DataGridView显示查询结果...

public partial class MainForm : Form
{
    public MainForm() => InitializeComponent();
    enum QueryType{All, Min, Max, }
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        dataGridView.DataSource = DataSource;
        dataGridView.AllowUserToAddRows = false;

        // Format columns
        DataSource.Add(new Product("Template"));
        dataGridView.Columns[nameof(Product.Description)].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
        var priceColStyle = dataGridView.Columns[nameof(Product.Price)].DefaultCellStyle;
        priceColStyle.Format = "F2";
        priceColStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
        priceColStyle.Padding = new Padding(0, 0, 10, 0);
        DataSource.Clear();

        comboBox.Items.AddRange(Enum.GetNames(typeof(QueryType)));
        comboBox.SelectedIndexChanged += onCBSelectedIndexChanged;
        comboBox.SelectedIndex = 0;
    }
}
BindingList<Product> DataSource { get; } = new BindingList<Product>();

但是,当您执行查询时,它需要在某个 * 其他 * 产品集合上,而不是对DataSource本身的循环引用。

private void onCBSelectedIndexChanged(object sender, EventArgs e)
{
    DataSource.Clear();
    switch (Enum.Parse(typeof(QueryType), comboBox.Text))
    {
        case QueryType.All:
            foreach (var product in ProductDatabase) DataSource.Add(product);
            break;
        case QueryType.Min:
            DataSource.Add(ProductDatabase.OrderBy(_=>_.Price).First());
            break;
        case QueryType.Max:
            DataSource.Clear();
            DataSource.Add(ProductDatabase.OrderByDescending(_ => _.Price).First());
            break;
        default:
            break;
    }
    dataGridView.ClearSelection();
}

WHERE ProductDatabase是与此处创建的模拟数据库类似的产品集合:

public Product[] ProductDatabase { get; } = new Product[]
{
    new Product ("Sponge"),
    new Product ("Kite"),
    new Product ("Card"),
    new Product ("Hat"),
    new Product ("Potato"),
    new Product ("Shoes"),
    new Product ("Cactus"),
    new Product ("Whistle"),
    new Product ("Paper"),
    new Product ("Glass"),
    new Product ("Crayon"),
    new Product ("Feather"),
    new Product ("Vegetables"),
    new Product ("Rake"),
    new Product ("Rice"),
    new Product ("Bucket"),
    new Product ("Yarn "),
    new Product ("Salt"),
    new Product ("Flowers"),
    new Product ("Flour"),
};

地点:

public class Product
{
    static Random _rando = new Random(1);
    public Product(string description) => Description = description;
    public string Description { get; }
    public decimal Price { get; } = (decimal)_rando.NextDouble() * 10;
}

总结,如果您停止用查询结果覆盖原始“数据库”,那么后续查询运行时应该没有问题。

相关问题