как фильтровать таблицу по поиску?
Столкнулся с проблемой, что не понимаю как через textbox сфильтровать таблицу по столбцу фио. Не могу понять, как именно по нужному столбцу это проверять.
private void textbox1_TextChanged(object sender, TextChangedEventArgs e)
{
var tbx = sender as TextBox;
if(tbx.Text!="")
{
clientGrid.Items[0].Where();
}
}
это все что я смог. Хотелось бы узнать все же как это сделать.
P.S.

Таблица для фильтрации и ее textbox.
Фото с привязкой к столбцам.
public Window1()
{
InitializeComponent();
conn.FillGrid(sql, clientGrid);
}
string sql = "SELECT fio,bonus_card FROM client ";
public void FillGrid(string sql, DataGrid dataGrid)
{
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
connection.Open();
using (MySqlCommand cmdSel = new MySqlCommand(sql, connection))
{
DataTable dt = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter(cmdSel);
da.Fill(dt);
dataGrid.ItemsSource = dt.DefaultView;
}
connection.Close();
}
}
Ответы (1 шт):
Вы идете совершенно не правильным, я даже назвал бы наверно "варварским" путем. В WPF принято первым делом использовать XAML и Привязки (Binding). Если вы это не используете, храните данные в тесной связи с UI контролами, то вы получаете очень много проблем (от трудного проектирования, до проблем с производительностью).
Покажу самый простой пример, где будет фильтрация на клиенте, с привязкой.
Создадим класс, который будет работать с базой данных, назовем просто
DataBase. В нем прописываем все методы получения и отправки всех нужных данных, например:public record User(int Id, string Name); public class DataBase { public IEnumerable<User> GetAllUsers() { DataTable table = new DataTable(); table.Columns.Add("Id", typeof(int)); table.Columns.Add("Name"); table.Rows.Add(1, "Вася"); table.Rows.Add(2, "Петя"); table.Rows.Add(3, "Коля"); return table.AsEnumerable() .Select(x => new User(x.Field<int>("Id"), x.Field<string>("Name"))); } }Я здесь эмулировал класс
DataTable(чтоб его...), с неким набором данных, и привел их к простой коллекции объектовUser(наш простой класс, который содержит нужные свойства).Дальше создаем класс, который будет источником данных для всего приложения. Пусть зовется
MainViewModel(почему такие названия, можете почитать про MVVM подход, но сейчас не о нем). В этом классе нам надо получить объект нашей базы данных, создать свойства для привязок, запросить данные из базы. Получаем примерно следующее:public class MainViewModel { private readonly DataBase data = new(); public MainViewModel() { Users = new CollectionViewSource { Source = data.GetAllUsers() }.View; } public ICollectionView Users { get; } private string _searchText; public string SearchText { get => _searchText; set { _searchText = value; Users.Filter = x => { var user = x as User; return value.Length > 0 ? user.Name.StartsWith(value) : true; }; } } }Как видите, все просто, мы делаем объект нашей базы данных (в моем случае просто создаю, в вашем наверно надо передать через конструктор или еще что), делаем коллекцию, тип которой
ICollectionView, связываем их черезCollectionViewSource. Остается свойствоSearchText- это простое свойство, которое будет содержать текст, вверенный пользователем в текстовое поле, в его сеттере мы задаем фильтр, некое условие, которое вернет намtrue(объект надо отобразить) иfalse(объект не стоит отображать). Само условие простое - если у строки 0 символов, тоtrue, если больше 0, то ищем по началу имени.Задаем
DataContextокну, просто пишем в его конструктореDataContext = new MainViewModel();, этого нам будет пока достаточно.Все, данные у нас отвязаны, как видите мы до сих пор не использовали что либо из UI, ибо нам это и не нужно, наш UI должен быть максимально отделен от данных, в этом суть WPF с его MVVM и прочими подходами. Имея все это, мы теперь можем написать XAML, например такой простой:
<Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition /> </Grid.RowDefinitions> <Grid Margin="5"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <TextBlock Text="Фильтровать по человеку:" /> <TextBox Grid.Column="1" BorderThickness="0,0,0,1" Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}" /> </Grid> <DataGrid Grid.Row="1" ItemsSource="{Binding Users}" /> </Grid>Тут я думаю объяснять ничего не надо, кроме всяких
{Binding ...}- это привязка, через нее мы задаем свойству контрола некое место, от куда он должен забирать данные, например{Binding Users}, этоpublic ICollectionView Users { get; }из класса, который мы указали какDataContextокну. Еще тут интересным может бытьUpdateSourceTrigger=PropertyChanged- так мы задали привязки когда именно ей обновлять свойство, конкретноPropertyChangedозначает "Сразу при обновлении", другими словами, привязанное свойствоSearchTextбудет получать сразу введенные данные, а не в момент потери фокуса контрола (по умолчанию).
Все, при запуске у нас будут выведены все данные:
Ну а если мы напишем что-либо в текстовое поле, нам благополучно отфильтрует все:
Вот вам и фильтрация на клиенте в WPF проекте. Но учтите, если у вас идет работа с базой, то фильтрация ее уровень, вы не должны вообще хотеть загружать на клиент всех пользователей из базы, это очень ресурсоемкая задача. Поэтому очень продумывайте такие аспекты, если у вас уже готовые данные, которые вы вывели и в них нужна фильтрация - мой пример подойдет, а если данные в базе, и на их основе надо вывести что-то конкретное, то делаете в базу конкретный запрос и выводите уже потом эти данные.


