Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Редактирование. Чтобы редактировать значения, должен быть какой-то способ узнать

Читайте также:
  1. Команды панели «Редактирование» объекта
  2. Меню Edit — редактирование
  3. Построение и редактирование диаграмм
  4. Редактирование
  5. Редактирование выделения
  6. Редактирование и копирование документа

Чтобы редактировать значения, должен быть какой-то способ узнать, что значение изменилось. Помимо разрешения изменять свойство, существует несколько интерфейсов, которые позволяют объекту или списку рассылать извещения об изменении. Если источник данных уведомляет об изменении, то система связывания сможет отреагировать на модификацию данных. Чтобы наделить наш класс Person способностью извещать об изменениях, у нас есть три возможности:

· реализовать интерфейс INotifyPropertyChanged;

· добавить события, с помощью которых мы будем сообщать об изменении;

· создать свойства, производные от класса DependencyProperty.

Использование событий для извещения об изменениях свойств впервые было применено в.NET 1.0 и поддерживается механизмами связывания в Windows Forms и ASP.NET. Интерфейс INotifyPropertyChanged появился в.NET 2.0. Он оптимизирован для привязки к данным, обладает более высокой производительностью и проще как для авторов объектов, так и для самой системы связывания. Но использовать этот интерфейс в обычных сценариях, когда необходимо извещать об изменениях, несколько сложнее.

Применение свойств, производных от DependencyProperty, относительно просто, позволяет объекту воспользоваться преимуществами, которые дает разреженное хранилище, и хорошо сопрягается с другими службами WPF (например, с динамической привязкой к ресурсам и стилизацией). Подробно создание объектов со свойствами, производными от DependencyProperty, обсуждается в лекции о User/Custom control’ах.

Все три способа во время выполнения демонстрируют одинаковое поведение. Вообще говоря, при создании модели данных лучше реализовать интерфейс INotifyPropertyChanged. Для использования свойств, производных от DependencyProperty, требуется, чтобы класс объекта наследовал DependencyObject, а это, в свою очередь, означает, что объект данных должен работать в STA-потоке. Применение событий для извещения об изменениях свойств приводит к разбуханию объектной модели; в общем случае этот механизм лучше оставить для свойств, которые разработчики и так привыкли отслеживать:

public class Name: INotifyPropertyChanged
{
...
public string First
{
get { return _first; }
set
{
_first = value;
NotifyChanged(“First”);
}
}
...
public event PropertyChangedEventHandler PropertyChanged;
void NotifyChanged(string property)
{
if (PropertyChanged!= null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}

Раз мы применяем один и тот же паттерн ко всем трем объектам данным, то можем изменить пользовательский интерфейс и воспользоваться преимуществами новой реализации объектов. Мы заведем два неизменяемых текстовых поля (TextBlock) для отображения текущего имени и два объекта TextBox для редактирования значений. Поскольку класс Name реализует интерфейс INotifyPropertyChanged, то при изменении значений система связывания получит извещение, что приведет к обновлению объектов TextBlock:

<Window... Text=’Object Binding’>
<StackPanel>
<TextBlock Text=’{Binding Path=Name.First}’ />
<TextBlock Text=’{Binding Path=Name.Last}’ />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Grid.Row=’0’ Grid.Column=’0’>First</Label>
<TextBox Grid.Row=’0’ Grid.Column=’1’
Text=’{Binding Path=Name.First}’ />
<Label Grid.Row=’1’ Grid.Column=’0’>Last</Label>
<TextBox Grid.Row=’1’ Grid.Column=’1’
Text=’{Binding Path=Name.Last}’ />
</Grid>
</StackPanel>
</Window>

Ввод в любое текстовое поле обновляет соответствующую область окна. Отметим, что изменение происходит только при выходе из поля. По умолчанию элемент TextBox обновляет данные только в момент потери фокуса. Чтобы изменить это поведение, нужно указать, что привязка должно обновляться при любом изменении значения свойства. Для этого служит свойство привязки UpdateSourceTrigger:

<TextBox Grid.Row=’1’ Grid.Column=’1’
Text=’{Binding Path=Name.Last, UpdateSourceTrigger=PropertyChanged }’/>

Списки сложнее простого изменения свойств. Для связывания необходимо знать, какие элементы были добавлены или удалены. С этой целью в WPF введен интерфейс INotifyCollectionChanged, в котором определено единственное событие CollectionChanged с аргументом такого типа:

public class NotifyCollectionChangedEventArgs: EventArgs
{
public NotifyCollectionChangedAction Action { get; }
public IList NewItems { get; }
public int NewStartingIndex { get; }
public IList OldItems { get; }
public int OldStartingIndex { get; }
}

public enum NotifyCollectionChangedAction
{
Add,
Remove,
Replace,
Move,
Reset,
}

В нашем примере мы можем поддержать динамическое добавление и удаление адресов человека. Проще всего это реализуется в помощью класса ObservableCollection<T>, который наследует Collection<T> и дополнительно реализует интерфейс INotifyCollectionChanged:

public class Person: INotifyPropertyChanged
{
IList<Address> _addresses = new ObservableCollection<Address>();
...
}

Теперь можно модифицировать наше приложение так, чтобы все адреса отображались в списковом поле, и реализовать пользовательский интерфейс для ввода новых адресов и добавления их в список:

<!— window1.xaml —>
...
<StackPanel>
<ListBox ItemsSource=’{Binding Path=Addresses}’/>
<Button Click=’Add’ Grid.Row=’4’>Add</Button>
</StackPanel>

// window1.xaml.cs

void Add(object sender, RoutedEventArgs e)
{
Address a = new Address();
a.Street1 = _street.Text;
a.City = _city.Text;
((Person)DataContext).Addresses.Add(a);
}

В текстовые поля можно вводить новую информацию, а при нажатии кнопки Add список адресов обновляется. Поскольку свойство Addresses реализует интерфейс INotifyCollectionChanged, система связывания получает извещение о новом адресе и корректно обновляет пользовательский интерфейс.

Привязка к объектам CLR – процедура по большей части автоматическая. Реализовав интерфейсы INotifyPropertyChanged и INotifyCollectionChanged, мы наделяем источник данных “интеллектом”.


Дата добавления: 2015-08-13; просмотров: 88 | Нарушение авторских прав


Читайте в этой же книге: Повышение полномочий для приложений в браузере | Работа с текстом | Отладка при связывании с данными | Улучшенная поддержка шаблона MVVM | Неявные шаблоны | Другие изменения | Версия Visual Studio 2010 позволяет проектировать приложения, ориентированные на различные версии .NET. Напишите минимально допустимую версию .NET (ответ версии через точку). | Задача 4. | Ресурсы | Основные принципы связывания |
<== предыдущая страница | следующая страница ==>
Привязка к объектам CLR| Краткие итоги

mybiblioteka.su - 2015-2024 год. (0.008 сек.)