Фильтрация в DataGridView через выбор в ComboBox
Мне нужно, чтобы comboBox фильтровал dataGridView, например, я выбираю coupe и только 86 и Supra будут отображены.
Также, если я 2 раза кликну по нужной мне модели другое окно откроется 
Мне нужно, чтобы данные тут тоже фильтровались.
У меня есть 2 класса
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Toyota_beta
{
public class Models
{
public string Model { get; set; }
public string Year { get; set; }
public string Type { get; set; }
public string Price { get; set; }
public List<Cars> Cars { get; set; }
public Models(string model, string type, string year,
string price, List<Cars> cars)
{
Model = model; Year = year; Type = type;
Price = price; Cars = cars;
}
public Models()
{
Cars = new List<Cars>();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Toyota_beta
{
public class Cars
{
public string Model { get; set; }
public int Year { get; set; }
public string Transmission { get; set; }
public string Drive { get; set; }
public int Hp { get; set; }
public string Engine { get; set; }
public int Price { get; set; }
public Cars(string model, int year, string transmission, string drive, string engine,
int hp, int price)
{
Model = model; Year = year; Transmission = transmission;
Drive = drive; Hp = hp; Engine = engine; Price = price;
}
public Cars()
{ }
}
}
И все данные в dataGridView я вставил вручную
namespace Toyota_beta
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public List<Models> listM = new List<Models>();
public List<Cars> listC;
private void Form1_Load(object sender, EventArgs e)
{
//Yaris---------------------------------------------------------------------------------------------
listC = new List<Cars>();
listC.Add(new Cars("Yaris L", 2020, "Manual", "FWD", "Fuel", 106, 15650));
listC.Add(new Cars("Yaris XLE", 2020, "Automatic", "FWD", "Fuel", 106, 18750));
listM.Add(new Models("Yaris ", "Sedan", "2020", "from 15,650$", listC));
//Yaris Hatchback---------------------------------------------------------------------------------------------
listC = new List<Cars>();
listC.Add(new Cars("Yaris LE Hatchback", 2020, "Automatic", "FWD", "Fuel", 106, 17750));
listM.Add(new Models("Yaris Hatchback", "Hatchback", "2020", "from 17,750$", listC));
//Corolla---------------------------------------------------------------------------------------------
listC = new List<Cars>();
listC.Add(new Cars("Corolla L", 2020, "Automatic", "FWD", "Fuel", 139, 19600));
listC.Add(new Cars("Corolla LE", 2020, "Automatic", "FWD", "Fuel", 139, 20050));
listC.Add(new Cars("Corolla Hybrid LE", 2020, "Automatic", "FWD", "Fuel", 169, 23100));
listM.Add(new Models("Cororlla", "Sedan", "2020", "from 19,600$", listC));
...
Вот как я заполнил второе dataGridView
private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1.CurrentRow == null || dataGridView1.CurrentRow.Index == dataGridView1.RowCount - 1)
return;
Info formC = new Info();
int n = dataGridView1.CurrentRow.Index;
formC.carsBindingSource.DataSource = listM[n].Cars;
formC.ShowDialog();
modelsBindingSource.ResetCurrentItem();
}
Мб эти скриншоты помогут понять общую ситуацию
Вот что я пробовал сделать сам: создать bool method который отбирает ряды dataGridView, которые надо показывать или нет, но у меня постоянно разные проблемы
private void b_Show_Click(object sender, EventArgs e)
{
bool select = false;
dataGridView1.CurrentCell = null;
for (int i = 0; i < dataGridView1.RowCount - 1; i++)
{
if (TestRow(i))
dataGridView1.Rows[i].Visible = true;
else
{
dataGridView1.Rows[i].Visible = false;
select = true;
}
}
}
private bool TestRow(int c)
{
Cars crs = Form1.listM[m];
if (comboBox_type.Text != "" &&
!crs.Type.Contains(comboBox_type.Text)) return false;
}
Не бейте, если мой код похож на какашку, я только пытаюсь разобраться в c#. Заранее спасибо!
Ответы (1 шт):
Работу с данными надо выделять в отдельный класс.
public class AppData
{
private List<Model> _models;
public AppData()
{
var listY = new List<Car>();
listY.Add(new Car("Yaris L", 2020, "Manual", "FWD", "Fuel", 106, 15650));
listY.Add(new Car("Yaris XLE", 2020, "Automatic", "FWD", "Fuel", 106, 18750));
var listYH = new List<Car>();
listYH.Add(new Car("Yaris LE Hatchback", 2020, "Automatic", "FWD", "Fuel", 106, 17750));
var listC = new List<Car>();
listC.Add(new Car("Corolla L", 2020, "Automatic", "FWD", "Fuel", 139, 19600));
listC.Add(new Car("Corolla LE", 2020, "Automatic", "FWD", "Fuel", 139, 20050));
listC.Add(new Car("Corolla Hybrid LE", 2020, "Automatic", "FWD", "Fuel", 169, 23100));
listC.Add(new Car("Corolla LE", 2018, "Automatic", "AWD", "Fuel", 139, 21500));
listC.Add(new Car("Corolla", 2019, "Manual", "AWD", "Fuel", 139, 22500));
listC.Add(new Car("Corolla L", 2017, "Manual", "AWD", "Fuel", 139, 18500));
_models = new List<Model>
{
new Model("Yaris ", "Sedan", "2020", "from 15,650$", listY),
new Model("Yaris Hatchback", "Hatchback", "2020", "from 17,750$", listYH),
new Model("Cororlla", "Coupe", "2020", "from 19,600$", listC)
};
}
public IEnumerable<Model> GetModels() => _models.AsEnumerable();
public IEnumerable<string> GetModelsTypes() => _models.Select(m => m.Type);
public IEnumerable<Model> GetModelsByType(string type) =>
_models.Where(m => m.Type.Equals(type));
}
Тогда и форма становится проще
public partial class FormMain : Form
{
//источник данных для DGV
private BindingSource _bsModels;
//данные
private AppData _appData;
public FormMain()
{
InitializeComponent();
_appData = new AppData();
_bsModels = new BindingSource();
//привязки DGV & столбцов
_dataGridView.AutoGenerateColumns = false;
_dataGridView.DataSource = _bsModels;
_columnTitle.DataPropertyName = nameof(Model.Title);
_columnYear.DataPropertyName = nameof(Model.Year);
_columnType.DataPropertyName = nameof(Model.Type);
_columnPrice.DataPropertyName = nameof(Model.Price);
this.Load += FormMain_Load;
}
private void FormMain_Load(object sender, EventArgs e)
{
//заполняем DGV
_appData.GetModels()
.ToList()
.ForEach(m => _bsModels.Add(m));
//заполняем комбобокс
var types = new List<string> { "Все" };
types.AddRange(_appData.GetModelsTypes());
_comboBoxType.DataSource = types;
//подписка на выбор в комбобксе
_comboBoxType.SelectedIndexChanged += ComboBoxType_SelectedIndexChanged;
//подписка на 2-й клик в DGV
_dataGridView.CellDoubleClick += DataGridView_CellDoubleClick;
}
private void ComboBoxType_SelectedIndexChanged(object sender, EventArgs e)
{
//очищаем DGV
_bsModels.Clear();
var type = (sender as ComboBox).Text;
if (type != "Все")
{
//заполняем нужным типом
_appData.GetModelsByType(type)
.ToList()
.ForEach(m => _bsModels.Add(m));
}
else
{
//извлекаем, заполняем полным списком
_appData.GetModels()
.ToList()
.ForEach(m => _bsModels.Add(m));
}
}
private void DataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
//определяем выбранную в DGV модель
var model = _bsModels.Current as Model;
//создаем экз.формы с передачей выбранной модели
var formCars = new FormCars(model);
formCars.Owner = this;
formCars.ShowDialog();
}
}
Весь пример целиком здесь.

