[Элементы управления](./t8_elements.md) | [Содержание](../readme.md#тема-8-оконные-приложения) | [Фильтрация данных](./wpf_filtering.md)
# Каркас приложения. Модель данных. Привязка данных. Табличный вывод.
## Каркас приложения.
На прошлых занятиях и лекциях мы разработали каркас для наших будущих приложений. Рассмотрим его ещё раз:

* В левой колонке **(1)** у нас будет элемент **StackPanel**, объединяющий все три строки. В нём будут находится логотип компании и основное меню приложения. Эта колонка имеет фиксированную ширину.
* В верхней строке правой колонки **(2)** будет расположено меню для элементов фильтрации, поиска и т.д. Эта строка имеет высоту "Auto", т.е. будет зависеть от содержимого.
* В середине второй колонки **(3)** будет расположен основной список с данными: элементы **DataGrid** или **ListView**
* В нижней строке второй колонки **(4)** в перспективе будем располагать счётчики, пагинаторы и т.п. (высота тоже "auto")
Разметка выглядит так:
```xml
```
>Для того, чтобы картинки были видны в рантайме нужно их поместить а ресурсы:
>
>
## Модель данных
В следующем году мы будем получать данные из базы данных, а пока будем экспериментировать на "кошках". Заодно оформим получение данных в виде интерфейса.
>В заданиях WorldSkills есть требование логически выделять модели. Поэтому создадим в проекте папку **Model** (в контекстном меню *решения* выбрать *добавить - создать папку*)
>
>
1. Создадим классы **Cat (Кошка)** и **CatBreed (порода кошки)** (в контекстном меню папки *Model* выбрать *Добавить - класс*):
```catbreed.cs
namespace WpfTemplate.Model
{
public class CatBreed
{
public string title { get; set; }
}
}
```
```cat.cs
namespace WpfTemplate.Model
{
public class Cat
{
public string name { get; set; }
public int age{ get; set; }
public string color { get; set; }
public string photo { get; set; }
// порода
public CatBreed breed { get; set; }
}
}
```
>Студия может не добавить модификатор доступа классам - допишите **public**
1. Для работы с данными создадим интерфейс **IDataProvider** (поставщик данных) и класс **LocalDataProvider**, реализующий этот интерфейс (это уже не модель, а прочие классы, поэтому их создаём в каталоге `Classes`)
В интерфейсе нам пока нужен только один метод: получение списка кошек
```cs
namespace WpfTemplate.Classes
{
interface IDataProvider
{
IEnumerable getCats();
}
}
```
Метод *GetCats* класса **LocalDataProvider** возвращает список кошек, созданный программно
```cs
namespace WpfTemplate.Classes
{
public class LocalDataProvider : IDataProvider
{
public IEnumerable getCats()
{
return new Cat[]{
new Cat{
age=1,
breed = new CatBreed() { title = "Дворняжка" },
color="Белый",
name="Ириска"},
new Cat{
age=2,
breed = new CatBreed() { title = "Шотландская вислоухая" },
color="Коричневый",
name="Изи"},
new Cat{
age=3,
breed = new CatBreed() { title = "Сиамский" },
color="Цветной",
name="Макс"}
};
}
}
}
```
1. В пространстве имен проекта создадим класс **Globals**, в котором объявим публичную статическую переменную *dataProvider* типа **IDataProvider**:
```cs
namespace WpfTemplate.Classes
{
class Globals
{
public static IDataProvider dataProvider;
}
}
```
Это нужно, чтобы поставщик данных был виден в любом месте проекта.
1. В конструкторе главного окна (`MainWindow.xaml.cs`) присвоим глобальной переменной *dataProvider* экземпляр класса **LocalDataProvider** и сохраним список кошек в свойстве **catList**
```cs
public IEnumerable catList { get; set; }
public MainWindow()
{
InitializeComponent();
DataContext = this;
Globals.dataProvider = new LocalDataProvider();
catList = Globals.dataProvider.getCats();
}
private void ExitButton_Click(
object sender,
RoutedEventArgs e)
{
Application.Current.Shutdown();
}
```
## Привязка данных. Табличный вывод
Теперь, имея данные для отображения, мы можем разместить в разметке элемент **DataGrid** и "привязать" к нему данные:
```xml
```
* Атрибут `CanUserAddRows="False"` запрещает элементу **DataGrid** добавлять строки с таблицу
* Атриут `AutoGenerateColumns="False"` запрещает автоматическое формирование столбцов таблицы - мы вручную описываем те столбцы, которые хотим видеть.
* Атрибут `ItemsSource="{Binding catList}"` "привязывает" к таблице источник данных - наш список кошек.
* В колонках таблицы мы уже "привязываемся" к свойствам класса источника данных
Приложение должно выглядеть примерно так:

---
## Задание
Реализовать приложение из лекции и оформить отчет со скриншотами в репозиторий.
**Требования к репозиторию:**
- в репозитории должны быть исходные коды проекта (весь каталог проекта)
- в репозитории не должно быть бинарных файлов (каталоги `bin`, `obj` и `.vs` для C#) - используйте файл `.gitignore`
- в корне репозитория должен быть файл `readme.md` с отчётом о проекте
- в отчёте должны быть:
- заголовок (с названием конспекта или лабораторной)
- блоки кода (не весь проект, а только наиболее важные куски, относящиеся к теме лекции/лабораторной) - скриншоты работающего приложения.
Например, ваш проект называется `SomeProject`, в таком случае структура файлов в репозитории должна быть примерно такая:
- `img` (каталог со скринами для отчета)
- `SomeProject` (каталог с проектом)
- `SomeProject.sln`
- `.gitignore`
- `readme.md`
[Элементы управления](./t8_elements.md) | [Содержание](../readme.md#тема-8-оконные-приложения) | [Фильтрация данных](./wpf_filtering.md)