Читать книги » Книги » Компьютеры и Интернет » Программирование » Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Читать книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен, Эндрю Троелсен . Жанр: Программирование.
Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен
Название: Язык программирования C#9 и платформа .NET5
Дата добавления: 26 август 2023
Количество просмотров: 560
(18+) Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних просмотр данного контента СТРОГО ЗАПРЕЩЕН! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту для удаления материала.
Читать онлайн

Язык программирования C#9 и платформа .NET5 читать книгу онлайн

Язык программирования C#9 и платформа .NET5 - читать онлайн , автор Эндрю Троелсен

В 10-м издании книги описаны новейшие возможности языка C# 9 и .NET 5 вместе с подробным "закулисным" обсуждением, призванным расширить навыки критического мышления разработчиков, когда речь идет об их ремесле.
Книга охватывает ASP.NET Core, Entity Framework Core и многое другое наряду с последними обновлениями унифицированной платформы .NET, начиная с улучшений показателей производительности настольных приложений Windows в .NET 5 и обновления инструментария XAML и заканчивая расширенным рассмотрением файлов данных и способов обработки данных.
Все примеры кода были переписаны с учетом возможностей последнего выпуска C# 9.

Перейти на страницу:
class="code">Car и присвойте его свойству ItemsSource элемента ComboBox. Кроме того, добавьте оператор using для пространства имен WpfNotifications.Models.

using WpfNotifications.Models;

// Для краткости код не показан.

public partial class MainWindow : Window

{

  readonly IList<Car> _cars = new List<Car>();

  public MainWindow()

  {

    InitializeComponent();

    _cars.Add(new Car {Id = 1, Color = "Blue", Make = "Chevy",

                       PetName = "Kit"});

    _cars.Add(new Car {Id = 2, Color = "Red", Make = "Ford",

                       PetName = "Red Rider"});

    cboCars.ItemsSource = _cars;

    }

}

Запустите приложение. Вы увидите, что в поле со списком Vehicle для выбора доступны два варианта автомобилей. Выбор одного из них приводит к автоматическому заполнению текстовых полей сведениями об автомобиле. Измените цвет одного из автомобилей, выберите другой автомобиль и затем возвратитесь к автомобилю, запись о котором редактировалась. Вы обнаружите, что новый цвет по-прежнему связан с автомобилем. Здесь нет ничего примечательного, просто демонстрируется мощь привязки данных XAML.

Изменение данных об автомобиле в коде

Несмотря на то что предыдущий пример работает ожидаемым образом, когда данные изменяются программно, пользовательский интерфейс не отразит изменения до тех пор, пока в приложении не будет предусмотрен код для обновления данных. Чтобы проиллюстрировать сказанное, добавьте обработчик события Click для кнопки btnChangeColor:

Button x:Name="btnChangeColor" Content="Change Color" Margin="5,0,5,0"

    Padding="4, 2" Click="BtnChangeColor_OnClick"/>

Внутри обработчика события BtnChangeColor_OnClick() с помощью свойства SelectedItem элемента управления ComboBox отыщите выбранную запись в списке автомобилей и измените ее цвет на Pink:

private void BtnChangeColor_OnClick(object sender, RoutedEventArgs e)

{

  _cars.First(x => x.Id == ((Car)cboCars.SelectedItem)?.Id).Color = "Pink";

}

Запустите приложение, выберите автомобиль и щелкните на кнопке Change Color (Изменить цвет). Никаких видимых изменений не произойдет. Выберите другой автомобиль и затем снова первоначальный. Теперь вы заметите обновленное значение. Для пользователя такое поведение не особенно подходит.

Добавьте обработчик события Click для кнопки btnAddCar:

<Button x:Name="btnAddCar" Content="Add Car" Margin="5,0,5,0" Padding="4, 2"

  Click="BtnAddCar_OnClick" />

В обработчике события BtnAddCar_OnClick() добавьте новую запись в список Car:

private void BtnAddCar_Click(object sender, RoutedEventArgs e)

{

  var maxCount = _cars?.Max(x => x.Id) ?? 0;

  _cars?.Add(new Car { Id=++maxCount,Color="Yellow",Make="VW",PetName="Birdie"});

}

Запустите приложение, щелкните на кнопке Add Car (Добавить автомобиль) и просмотрите содержимое элемента управления ComboBox. Хотя известно, что в списке имеется три автомобиля, в элементе ComboBox отображаются только два! Чтобы устранить обе проблемы, вы превратите класс Car в наблюдаемую модель и будете использовать наблюдаемую коллекцию для хранения всех экземпляров Car.

Наблюдаемые модели

Проблема с тем, что изменение значения свойства модели не отображается в пользовательском интерфейсе, решается за счет реализации классом модели Car интерфейса INotifyPropertyChanged. Интерфейс INotifyPropertyChanged содержит единственное событие PropertyChangedEvent. Механизм привязки XAML прослушивает это событие для каждого привязанного свойства в классах, реализующих интерфейс INotifyPropertyChanged. Вот как определен интерфейс INotifyPropertyChanged:

public interface INotifyPropertyChanged

{

  event PropertyChangedEventHandler PropertyChanged;

}

Добавьте в файл Car.cs следующие операторы using:

using System.ComponentModel;

using System.Runtime.CompilerServices;

Затем обеспечьте реализацию классом Car интерфейса INotifyPropertyChanged:

public class Car : INotifyPropertyChanged

{

  // Для краткости код не показан.

  public event PropertyChangedEventHandler PropertyChanged;

}

Событие PropertyChanged принимает объектную ссылку и новый экземпляр класса PropertyChangedEventArgs:

PropertyChanged?.Invoke(this,

  new PropertyChangedEventArgs("Model"));

Первый параметр представляет собой объект, который инициирует событие. Конструктор класса PropertyChangedEventArgs принимает строку, указывающую свойство, которое было изменено и нуждается в обновлении. Когда событие инициировано, механизм привязки ищет элементы управления, привязанные к именованному свойству данного объекта. В случае передачи конструктору PropertyChangedEventArgs значения String.Empty обновляются все привязанные свойства объекта.

Вы сами управляете тем, какие свойства вовлечены в процесс автоматического обновления. Автоматически обновляться будут только те свойства, которые генерируют событие PropertyChanged внутри блока set. Обычно в перечень входят все свойства классов моделей, но в зависимости от требований приложения некоторые свойства можно опускать. Вместо инициирования события PropertyChanged непосредственно в блоке set для каждого задействованного свойства распространенный подход предусматривает написание вспомогательного метода (как правило, называемого OnPropertyChanged()), который генерирует событие от имени свойств обычно в базовом классе для моделей. Добавьте в класс Car следующий метод:

protected void OnPropertyChanged([CallerMemberName] string propertyName = "")

{

  PropertyChanged?.Invoke(this,

    new PropertyChangedEventArgs(propertyName));

}

Модифицируйте каждое автоматическое свойство класса Car, чтобы оно имело полноценные блоки get и set, а также поддерживающее поле. В случае если значение изменилось, вызовите вспомогательный метод OnPropertyChanged(). Вот обновленное свойство Id:

private int _id;

public int Id

{

  get => _id;

  set

  {

    if (value == _id) return;

    _id = value;

    OnPropertyChanged();

  }

}

Проделайте аналогичную работу со всеми остальными свойствами в классе и снова запустите приложение. Выберите автомобиль и щелкните на кнопке Change Color. Изменение немедленно отобразится в пользовательском интерфейсе. Первая проблема решена!

Использование операции nameof

 В версии C# 6 появилась операция nameof, которая возвращает строковое имя переданного ей элемента. Ее можно применять в вызовах метода OnPropertyChanged() внутри блоков set, например:

public string Color

{

  get { return _color; }

  set

  {

    if (value == _color) return;

    _color = value;

    OnPropertyChanged(nameof(Color));

  }

}

Обратите внимание на то, что в случае использования операции nameof удалять атрибут [CallerMemberName] из метода OnPropertyChanged() необязательно (хотя он становится излишним). В конце концов, выбор между применением операции nameof или атрибута CallerMemberName зависит от личных предпочтений.

Наблюдаемые коллекции

 Следующей проблемой, которую необходимо решить, является обновление пользовательского интерфейса при изменении содержимого коллекции, что достигается путем

Перейти на страницу:
Комментарии (0)