|
@@ -1,147 +1,275 @@
|
|
-# Каркас приложения. Модель данных. Привязка данных. Табличный вывод.
|
|
|
|
-## Каркас приложения.
|
|
|
|
|
|
+# Поиск, сортировка ("Университет")
|
|
|
|
+## Поиск
|
|
```
|
|
```
|
|
-<Grid ShowGridLines="True">
|
|
|
|
- <Grid.RowDefinitions>
|
|
|
|
- <RowDefinition Height="auto"/>
|
|
|
|
- <RowDefinition />
|
|
|
|
- <RowDefinition Height="auto"/>
|
|
|
|
- </Grid.RowDefinitions>
|
|
|
|
- <Grid.ColumnDefinitions>
|
|
|
|
- <ColumnDefinition Width="200"/>
|
|
|
|
- <ColumnDefinition/>
|
|
|
|
- </Grid.ColumnDefinitions>
|
|
|
|
-
|
|
|
|
- <!-- типа логотип компании -->
|
|
|
|
- <Image
|
|
|
|
- Source="/Img/simon.png"
|
|
|
|
- Grid.RowSpan="2"/>
|
|
|
|
-
|
|
|
|
- <StackPanel
|
|
|
|
- Orientation="Vertical"
|
|
|
|
- Grid.RowSpan="3"
|
|
|
|
- VerticalAlignment="Bottom">
|
|
|
|
- <Button
|
|
|
|
- x:Name="ExitButton"
|
|
|
|
- Content="Выход"
|
|
|
|
- Click="ExitButton_Click"
|
|
|
|
- Height="50"/>
|
|
|
|
- </StackPanel>
|
|
|
|
-
|
|
|
|
- <WrapPanel
|
|
|
|
- Orientation="Horizontal"
|
|
|
|
- Grid.Column="1"
|
|
|
|
- MinHeight="50">
|
|
|
|
- <!-- минимальную высоту я тут поставил, чтобы верхнюю строку сетки было видно. В реальном приложении она не нужна -->
|
|
|
|
- </WrapPanel>
|
|
|
|
-</Grid>
|
|
|
|
-```
|
|
|
|
-![](./img/student.png)
|
|
|
|
-## Модель данных
|
|
|
|
-## 1.
|
|
|
|
-### Cоздадим класс "Student"
|
|
|
|
-```
|
|
|
|
-namespace WpfTemplate.Model
|
|
|
|
|
|
+using System;
|
|
|
|
+using System.Collections.Generic;
|
|
|
|
+using System.Linq;
|
|
|
|
+using System.Windows;
|
|
|
|
+using System.Windows.Controls;
|
|
|
|
+using System.Windows.Input;
|
|
|
|
+
|
|
|
|
+namespace University
|
|
{
|
|
{
|
|
- public class Cat
|
|
|
|
|
|
+ public partial class MainWindow : Window
|
|
{
|
|
{
|
|
- public string name { get; set; }
|
|
|
|
- public int age{ get; set; }
|
|
|
|
- public string course { get; set; }
|
|
|
|
- public string nation { get; set; }
|
|
|
|
- public string photo { get; set; }
|
|
|
|
|
|
+ private List<Student> students;
|
|
|
|
+ private Dictionary<string, Func<Student, bool>> filters;
|
|
|
|
+ private AgeRange selectedAge = new AgeRange { ageFrom = 19, ageTo = 23 };
|
|
|
|
+ private string searchFilter = "";
|
|
|
|
+
|
|
|
|
+ public MainWindow()
|
|
|
|
+ {
|
|
|
|
+ InitializeComponent();
|
|
|
|
+ SearchFilterTextBox.KeyUp += SearchFilter_KeyUp;
|
|
|
|
+ InitializeData();
|
|
|
|
+
|
|
|
|
+ // Отображаем всех студентов в listview
|
|
|
|
+ UpdateStudentList(students);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void InitializeData()
|
|
|
|
+ {
|
|
|
|
+ // Создаем список студентов
|
|
|
|
+ students = new List<Student>
|
|
|
|
+ {
|
|
|
|
+ new Student { Name = "Хэй Вэнь", Course = 3, Nationality = "Китаец", Age = 22 },
|
|
|
|
+ new Student { Name = "Эдвард Каллен", Course = 1, Nationality = "Американец", Age = 20 },
|
|
|
|
+ new Student { Name = "Джейк Ли", Course = 1, Nationality = "Китаец", Age = 19 },
|
|
|
|
+ new Student { Name = "Семен Хомяк", Course = 4, Nationality = "Русский", Age = 23 },
|
|
|
|
+ new Student { Name = "Эндрю Уилсон", Course = 3, Nationality = "Американец", Age = 21 },
|
|
|
|
+ new Student { Name = "Ариадна Санчес", Course = 2, Nationality = "Испанец", Age = 20 }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // Создаем словарь фильтров
|
|
|
|
+ filters = new Dictionary<string, Func<Student, bool>>
|
|
|
|
+ {
|
|
|
|
+ { "Все", s => true },
|
|
|
|
+ { "Первый курс", s => s.Course == 1 },
|
|
|
|
+ { "Второй курс", s => s.Course == 2 },
|
|
|
|
+ { "Третий курс", s => s.Course == 3 },
|
|
|
|
+ { "Четвертый курс", s => s.Course == 4 },
|
|
|
|
+ { "Русские", s => s.Nationality == "Русский" },
|
|
|
|
+ { "Китайцы", s => s.Nationality == "Китаец" },
|
|
|
|
+ { "Американцы", s => s.Nationality == "Американец" },
|
|
|
|
+ { "Испанцы", s => s.Nationality == "Испанец" },
|
|
|
|
+ { "Возраст 19-20", s => s.Age >= 19 && s.Age <= 20 },
|
|
|
|
+
|
|
|
|
+ { "Возраст 21-23", s => s.Age >= 21 && s.Age <= 23 }
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private IEnumerable<Student> FilteredStudentList
|
|
|
|
+ {
|
|
|
|
+ get
|
|
|
|
+ {
|
|
|
|
+ // сохраняем во временную переменную полный список
|
|
|
|
+ var res = students;
|
|
|
|
+
|
|
|
|
+ // фильтруем по возрасту
|
|
|
|
+ res = (List<Student>)res.Where(s => (s.Age >= selectedAge.ageFrom && s.Age < selectedAge.ageTo));
|
|
|
|
+
|
|
|
|
+ // если фильтр не пустой, то ищем ВХОЖДЕНИЕ подстроки поиска в имени без учета регистра
|
|
|
|
+ if (searchFilter != "")
|
|
|
|
+ res = (List<Student>)res.Where(s => s.Name.IndexOf(searchFilter, StringComparison.OrdinalIgnoreCase) >= 0);
|
|
|
|
+
|
|
|
|
+ return res;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void UpdateStudentList(List<Student> studentsToDisplay)
|
|
|
|
+ {
|
|
|
|
+ StudentListView.ItemsSource = studentsToDisplay;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void SearchFilter_KeyUp(object sender, KeyEventArgs e)
|
|
|
|
+ {
|
|
|
|
+ searchFilter = SearchFilterTextBox.Text;
|
|
|
|
+ UpdateStudentList(FilteredStudentList.ToList());
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-}
|
|
|
|
-```
|
|
|
|
-## 2.
|
|
|
|
-### Cоздадим интерфейс IDataProvider
|
|
|
|
-```
|
|
|
|
-namespace WpfTemplate.Model
|
|
|
|
-{
|
|
|
|
- interface IDataProvider
|
|
|
|
|
|
+
|
|
|
|
+ public class Student
|
|
{
|
|
{
|
|
- IEnumerable<Student> getStudents();
|
|
|
|
|
|
+ public string Name { get; set; }
|
|
|
|
+ public int Course { get; set; }
|
|
|
|
+ public string Nationality { get; set; }
|
|
|
|
+ public int Age { get; set; }
|
|
}
|
|
}
|
|
-}
|
|
|
|
-```
|
|
|
|
-### Создадим класс LocalDataProvider
|
|
|
|
-```
|
|
|
|
-public class LocalDataProvider : IDataProvider
|
|
|
|
-{
|
|
|
|
- public IEnumerable<Student> getStudents()
|
|
|
|
|
|
+
|
|
|
|
+ public class AgeRange
|
|
{
|
|
{
|
|
- return new Student[]{
|
|
|
|
- new Student{
|
|
|
|
- age=25,
|
|
|
|
- nation="Китаец",
|
|
|
|
- course="4",
|
|
|
|
- name="Хэй Вэнь"},
|
|
|
|
- new Student{
|
|
|
|
- age=23,
|
|
|
|
- nation="Англичанин",
|
|
|
|
- course="2",
|
|
|
|
- name="Джейкоб Уилсон"},
|
|
|
|
- new Student{
|
|
|
|
- age=19,
|
|
|
|
- nation="Испанец",
|
|
|
|
- course="1",
|
|
|
|
- name="Ариадна Санчес"}
|
|
|
|
- };
|
|
|
|
|
|
+ public int ageFrom { get; set; }
|
|
|
|
+ public int ageTo { get; set; }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
```
|
|
```
|
|
-## 3.
|
|
|
|
-### Cоздадим класс Globals
|
|
|
|
```
|
|
```
|
|
-class Globals
|
|
|
|
-{
|
|
|
|
- public static IDataProvider dataProvider;
|
|
|
|
-}
|
|
|
|
|
|
+<Window x:Class="University.MainWindow"
|
|
|
|
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
|
|
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
|
|
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
|
|
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
|
|
+ xmlns:local="clr-namespace:University"
|
|
|
|
+ mc:Ignorable="d"
|
|
|
|
+ Title="University" Height="450" Width="800">
|
|
|
|
+ <Grid>
|
|
|
|
+ <Grid.RowDefinitions>
|
|
|
|
+ <RowDefinition Height="Auto" />
|
|
|
|
+ <RowDefinition Height="*" />
|
|
|
|
+ </Grid.RowDefinitions>
|
|
|
|
+
|
|
|
|
+ <StackPanel Orientation="Horizontal" Margin="10">
|
|
|
|
+ <Label
|
|
|
|
+ Content="искать"
|
|
|
|
+ VerticalAlignment="Center"/>
|
|
|
|
+ <TextBox
|
|
|
|
+ Width="200"
|
|
|
|
+ VerticalAlignment="Center"
|
|
|
|
+ x:Name="SearchFilterTextBox"
|
|
|
|
+ KeyUp="SearchFilter_KeyUp"/>
|
|
|
|
+ </StackPanel>
|
|
|
|
+
|
|
|
|
+ <ListView x:Name="StudentListView" Grid.Row="1" Margin="10">
|
|
|
|
+ <ListView.View>
|
|
|
|
+ <GridView>
|
|
|
|
+ <GridViewColumn Header="Имя" DisplayMemberBinding="{Binding Name}" />
|
|
|
|
+ <GridViewColumn Header="Курс" DisplayMemberBinding="{Binding Course}" />
|
|
|
|
+ <GridViewColumn Header="Национальность" DisplayMemberBinding="{Binding Nationality}" />
|
|
|
|
+ <GridViewColumn Header="Возраст" DisplayMemberBinding="{Binding Age}" />
|
|
|
|
+ </GridView>
|
|
|
|
+ </ListView.View>
|
|
|
|
+ </ListView>
|
|
|
|
+ </Grid>
|
|
|
|
+</Window>
|
|
```
|
|
```
|
|
-## 4.
|
|
|
|
-### присвоим глобальной переменной dataProvider экземпляр класса LocalDataProvider
|
|
|
|
|
|
+![](./img/Снимок%20экрана%202024-04-27%20222231.png)
|
|
|
|
+## Сортировка
|
|
```
|
|
```
|
|
-public IEnumerable<Student> studentList { get; set; }
|
|
|
|
|
|
+using System;
|
|
|
|
+using System.Collections.Generic;
|
|
|
|
+using System.Linq;
|
|
|
|
+using System.Windows;
|
|
|
|
+using System.Windows.Controls;
|
|
|
|
|
|
-public MainWindow()
|
|
|
|
|
|
+namespace University
|
|
{
|
|
{
|
|
- InitializeComponent();
|
|
|
|
- DataContext = this;
|
|
|
|
- Globals.dataProvider = new LocalDataProvider();
|
|
|
|
- StudentList = Globals.dataProvider.getStudents();
|
|
|
|
-}
|
|
|
|
|
|
+ public partial class MainWindow : Window
|
|
|
|
+ {
|
|
|
|
+ private List<Student> students;
|
|
|
|
+ private bool sortAsc = true;
|
|
|
|
|
|
-private void ExitButton_Click(object sender, RoutedEventArgs e)
|
|
|
|
-{
|
|
|
|
- Application.Current.Shutdown();
|
|
|
|
|
|
+ public MainWindow()
|
|
|
|
+ {
|
|
|
|
+ InitializeComponent();
|
|
|
|
+
|
|
|
|
+ // Инициализируем список студентов
|
|
|
|
+ InitializeData();
|
|
|
|
+
|
|
|
|
+ // Отображаем всех студентов в listview
|
|
|
|
+ UpdateStudentList(students);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void InitializeData()
|
|
|
|
+ {
|
|
|
|
+ // Создаем список студентов
|
|
|
|
+ students = new List<Student>
|
|
|
|
+ {
|
|
|
|
+ new Student { Name = "Хэй Вэнь", Course = 3, Nationality = "Китаец", Age = 22 },
|
|
|
|
+ new Student { Name = "Эдвард Каллен", Course = 1, Nationality = "Американец", Age = 19 },
|
|
|
|
+ new Student { Name = "Джейк Ли", Course = 1, Nationality = "Китаец", Age = 19 },
|
|
|
|
+ new Student { Name = "Семен Хомяк", Course = 4, Nationality = "Русский", Age = 23 },
|
|
|
|
+ new Student { Name = "Эндрю Уилсон", Course = 2, Nationality = "Американец", Age = 21 },
|
|
|
|
+ new Student { Name = "Мария Гонсалес", Course = 3, Nationality = "Испанец", Age = 20 }
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void FilterComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
|
|
+ {
|
|
|
|
+ List<Student> filteredStudents = new List<Student>();
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ UpdateStudentList(filteredStudents);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void UpdateStudentList(List<Student> studentsToDisplay)
|
|
|
|
+ {
|
|
|
|
+ StudentListView.ItemsSource = studentsToDisplay;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void RadioButton_Checked(object sender, RoutedEventArgs e)
|
|
|
|
+ {
|
|
|
|
+ sortAsc = (sender as RadioButton).Tag.ToString() == "1";
|
|
|
|
+ InvalidateVisual(); // Исправлено имя метода
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private IEnumerable<Student> FilteredStudentList
|
|
|
|
+ {
|
|
|
|
+ get
|
|
|
|
+ {
|
|
|
|
+ // сохраняем во временную переменную полный список
|
|
|
|
+ var res = students;
|
|
|
|
+
|
|
|
|
+ return res;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ class Student
|
|
|
|
+ {
|
|
|
|
+ public string Name { get; set; }
|
|
|
|
+ public int Course { get; set; }
|
|
|
|
+ public string Nationality { get; set; }
|
|
|
|
+ public int Age { get; set; }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
```
|
|
```
|
|
-## Привязка данных. Табличный вывод
|
|
|
|
```
|
|
```
|
|
- <DataGrid
|
|
|
|
-Grid.Row="1"
|
|
|
|
-Grid.Column="1"
|
|
|
|
-CanUserAddRows="False"
|
|
|
|
-AutoGenerateColumns="False"
|
|
|
|
-ItemsSource="{Binding studentList}">
|
|
|
|
- <DataGrid.Columns>
|
|
|
|
- <DataGridTextColumn
|
|
|
|
- Header="Имя"
|
|
|
|
- Binding="{Binding Name}"/>
|
|
|
|
- <DataGridTextColumn
|
|
|
|
- Header="Возраст"
|
|
|
|
- Binding="{Binding Age}"/>
|
|
|
|
- <DataGridTextColumn
|
|
|
|
- Header="Курс"
|
|
|
|
- Binding="{Binding Course}"/>
|
|
|
|
- <DataGridTextColumn
|
|
|
|
- Header="Национальность"
|
|
|
|
- Binding="{Binding Nation}"/>
|
|
|
|
- </DataGrid.Columns>
|
|
|
|
- </DataGrid>
|
|
|
|
|
|
+<Window x:Class="University.MainWindow"
|
|
|
|
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
|
|
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
|
|
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
|
|
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
|
|
+ xmlns:local="clr-namespace:University"
|
|
|
|
+ mc:Ignorable="d"
|
|
|
|
+ Title="University" Height="450" Width="800">
|
|
|
|
+ <Grid>
|
|
|
|
+ <Grid.RowDefinitions>
|
|
|
|
+ <RowDefinition Height="Auto" />
|
|
|
|
+ <RowDefinition Height="*" />
|
|
|
|
+ </Grid.RowDefinitions>
|
|
|
|
+
|
|
|
|
+ <StackPanel Orientation="Horizontal" Margin="10">
|
|
|
|
+ <Label
|
|
|
|
+ Content="Возраст:"
|
|
|
|
+ VerticalAlignment="Center"/>
|
|
|
|
+ <RadioButton
|
|
|
|
+ GroupName="Age"
|
|
|
|
+ Tag="1"
|
|
|
|
+ Content="по возрастанию"
|
|
|
|
+ IsChecked="True"
|
|
|
|
+ Checked="RadioButton_Checked"
|
|
|
|
+ VerticalAlignment="Center"/>
|
|
|
|
+ <RadioButton
|
|
|
|
+ GroupName="Age"
|
|
|
|
+ Tag="2"
|
|
|
|
+ Content="по убыванию"
|
|
|
|
+ Checked="RadioButton_Checked"
|
|
|
|
+ VerticalAlignment="Center"/>
|
|
|
|
+ </StackPanel>
|
|
|
|
+
|
|
|
|
+ <ListView x:Name="StudentListView" Grid.Row="1" Margin="10">
|
|
|
|
+ <ListView.View>
|
|
|
|
+ <GridView>
|
|
|
|
+ <GridViewColumn Header="Имя" DisplayMemberBinding="{Binding Name}" />
|
|
|
|
+ <GridViewColumn Header="Курс" DisplayMemberBinding="{Binding Course}" />
|
|
|
|
+ <GridViewColumn Header="Национальность" DisplayMemberBinding="{Binding Nationality}" />
|
|
|
|
+ <GridViewColumn Header="Возраст" DisplayMemberBinding="{Binding Age}" />
|
|
|
|
+ </GridView>
|
|
|
|
+ </ListView.View>
|
|
|
|
+ </ListView>
|
|
|
|
+ </Grid>
|
|
|
|
+</Window>
|
|
```
|
|
```
|
|
-# ꒰ᐢ⸝⸝•༝•⸝⸝ᐢ꒱⸒⸒ 🧊
|
|
|
|
-![](./img/Снимок%20экрана%202024-04-27%20130501.png)
|
|
|
|
-#### Хэй Вэнь отчислился
|
|
|
|
-#### зато его брат остался тут
|
|
|
|
-![](./img/Снимок%20экрана%202024-04-24%20173558.png)
|
|
|
|
|
|
+![](./img/Снимок%20экрана%202024-04-28%20203454.png)
|