Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен
Шрифт:
Интервал:
Закладка:
Построение вкладки DataGrid
В предыдущем примере привязки данных иллюстрировался способ конфигурирования двух (или большего количества) элементов управления для участия в операции привязки данных. Наряду с тем, что это удобно, возможно также привязывать данные из файлов XML, базы данных и объектов в памяти. Чтобы завершить текущий пример, вы должны спроектировать финальную вкладку элемента управления DataGrid, которая будет отображать информацию, извлеченную из таблицы Inventory базы данных AutoLot.
Как и с другими вкладками, начните с замены текущего элемента Grid панелью StackPanel, напрямую обновив разметку XAML в Visual Studio. Внутри нового элемента StackPanel определите элемент управления DataGrid по имени gridInventory:
<TabItem x:Name="tabDataGrid" Header="DataGrid">
<StackPanel>
<DataGrid x:Name="gridInventory" Height="288"/>
</StackPanel>
</TabItem>
С помощью диспетчера пакетов NuGet добавьте в проект следующие пакеты:
• Microsoft.EntityFrameworkCore
• Microsoft.EntityFrameworkCore.SqlServer
• Microsoft.Extensions.Configuration
• Microsoft.Extensions.Configuration.Json
Если вы предпочитаете добавлять пакеты в интерфейсе командной строки .NET Core, тогда введите приведенные далее команды (в каталоге решения):
dotnet add WpfControlsAndAPIs package Microsoft.EntityFrameworkCore
dotnet add WpfControlsAndAPIs package Microsoft.EntityFrameworkCore.SqlServer
dotnet add WpfControlsAndAPIs package Microsoft.Extensions.Configuration
dotnet add WpfControlsAndAPIs package Microsoft.Extensions.Configuration.Json
Затем щелкните правой кнопкой мыши на имени решения, выберите в контекстном меню пункт Add►Existing Project (Добавить►Существующий проект) и добавьте проекты AutoLot.Dal и AutoLot.Dal.Models из главы 23, а также ссылки на эти проекты. Сделать это можно также с помощью интерфейса командной строки, выполнив показанные ниже команды (вам придется скорректировать пути к проектам согласно требованиям имеющейся операционной системы):
dotnet sln .Chapter25_AllProjects.sln add ..Chapter_23AutoLot.Models
dotnet sln .Chapter25_AllProjects.sln add ..Chapter_23AutoLot.Dal
dotnet add WpfControlsAndAPIs reference ..Chapter_23AutoLot.Models
dotnet add WpfControlsAndAPIs reference ..Chapter_23AutoLot.Dal
Убедитесь, что в проекте AutoLot.Dal все еще присутствует ссылка на проект AutoLot.Dal.Models. Добавьте в файл MainWindow.xaml.cs следующие пространства имен:
using System.Linq;
using AutoLot.Dal.EfStructures;
using AutoLot.Dal.Repos;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
Добавьте в MainWindow.cs два свойства уровня модуля для хранения экземпляров реализации IConfiguration и класса ApplicationDbContext:
private IConfiguration _configuration;
private ApplicationDbContext _context;
Добавьте новый метод по имени GetConfigurationAndContext() для хранения экземпляров реализации IConfiguration и класса ApplicationDbContext и вызовите его в конструкторе. Вот полный код метода:
private void GetConfigurationAndDbContext()
{
_configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", true, true)
.Build();
var optionsBuilder =
new DbContextOptionsBuilder<ApplicationDbContext>();
var connectionString =
_configuration.GetConnectionString("AutoLot");
optionsBuilder.UseSqlServer(connectionString,
sqlOptions => sqlOptions.EnableRetryOnFailure());
_context = new ApplicationDbContext(optionsBuilder.Options);
}
Добавьте в проект новый файл JSON по имени appsettings.json. Щелкните правой кнопкой мыши на имени этого файла в окне Solution Explorer, выберите в контекстном меню пункт Properties (Свойства) и установите свойство Copy То Output Directory (Копировать в выходной каталог) в Copy always (Всегда копировать). Вы можете добиться того же самого результата с помощью файла проекта:
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
Модифицируйте файл JSON, как показано ниже (приведя строку подключения в соответствие со своей средой):
{
"ConnectionStrings": {
"AutoLotFinal": "server=.,5433;Database=AutoLot;
User Id=sa;Password=P@ssw0rd;"
}
}
Откройте файл MainWindow.xaml.cs, добавьте последнюю вспомогательную функцию по имени ConfigureGrid() и вызовите ее в конструкторе после конфигурирования ApplicationDbContext. Понадобится добавить лишь несколько строк кода:
private void ConfigureGrid()
{
using var repo = new CarRepo(_context);
gridInventory.ItemsSource = repo
.GetAllIgnoreQueryFilters()
.ToList()
.Select(x=> new {
x.Id,
Make=x.MakeName,
x.Color,
x.PetName
});
}
Запустив проект, вы увидите данные, заполняющие сетку. При желании сделать сетку более привлекательной можно применить окно Properties в Visual Studio для редактирования свойств сетки, чтобы улучшить ее внешний вид.
На этом текущий пример завершен. В последующих главах вы увидите в действии другие элементы управления, но к настоящему моменту вы должны чувствовать себя увереннее с процессом построения пользовательских интерфейсов в Visual Studio, а также при работе с разметкой XAML и кодом С#.
Роль свойств зависимости
Подобно любому API-интерфейсу .NET Core внутри WPF используется каждый член системы типов .NET Core (классы, структуры, интерфейсы, делегаты, перечисления) и каждый член типа (свойства, методы, события, константные данные, поля только для чтения и т.д.). Однако в WPF также поддерживается уникальная программная концепция под названием свойство зависимости.
Как и "нормальное" свойство .NET Core (которое в литературе, посвященной WPF, часто называют свойством CLR), свойство зависимости можно устанавливать декларативно с помощью разметки XAML или программно в файле кода. Кроме того, свойства зависимости (подобно свойствам CLR) в конечном итоге предназначены для инкапсуляции полей данных класса и могут быть сконфигурированы как доступные только для чтения, только для записи или для чтения и записи.
Вы будете практически всегда пребывать в блаженном неведении относительно того, что фактически устанавливаете (или читаете) свойство зависимости, а не свойство CLR! Например, свойства Height и Width, которые элементы управления WPF наследуют от класса FrameworkElement, а также член Content, унаследованный от класса ControlContent, на самом деле являются свойствами зависимости:
<!-- Установить три свойства зависимости -->
<Button x:Name = "btnMyButton" Height = "50" Width = "100" Content = "OK"/>
С учетом всех указанных сходств возникает вопрос: зачем нужно было определять в WPF новый термин для такой знакомой концепции? Ответ кроется в способе реализации свойства зависимости внутри класса. Пример кода будет показан позже, а на высоком уровне все