Главная » C#, Компоненты » Несколько слов о привязке данных

0

Основная идея привязки данных — создать связь между источником данных и компонентом отображения (редактирования). Под связью имеется в виду автоматическое обновление отображения при изменении данных и обновление данных в источнике при редактировании их в компоненте. Привязка данных может быть простой (simple data binding) и сложной (complex data binding). Калька английских терминов не совсем очевидно отражает суть дела. Проще сказать, что простая привязка создает связь между источником данных и одной записью, а сложная — между источником данных и списком (рис. 13. ]). Общая схема работы привязки данных показана на рис. 13.2. Источником данных может служить любой класс, как минимум, реализующий интерфейс iList. Класс PropertyManager описывает связь свойства и источника данных, а класс CurrencyManager — СВЯЗЬ ИСТОЧНИКЭ данных И списка. Класс BindingContext

отвечает за хранение и управление привязкой. О прямой привязке свойств компонентов между собой я расскажу в разд. 13.5.

Рис. 13.1. Простая и сложная привязки данных

 

Рис. 13.2. Модель привязки данных

Чтобы не углубляться в "теорию", я покажу как работает механизм привязки данных на небольшом примере. Форма, показанная на рис. ]3.3, содержит шесть компонентов textBox И ОДИН компонент dataGridView. Для организации источника данных МЫ будем использовать класс Customer (листинг 13.]), содержащий три поля: id (уникальный номер), Name (имя), Rate (стоимость). Начнем с простой привязки. Компоненты textBox I, textBox2 и textBox3 привяжем к некоторому экземпляру класса customer следующим образом:

Customer customer = new Customer(0, "Mr. Zero", 10.0M);

this.textBoxl.DataBindings.AddC’Text", customer, "ID" ,          true) ;

this.textBox2.DataBindings.Add("Text", customer, "Name",         true);

this.textBox3.DataBindings.Add("Text", customer, "Name",         true);

Рис. 13.3. Привязка данных

public class Customer

1

private int id; private string name; private Decimal rate;

// Конструктор

public Customer() {

this.ID = -X;

this.Name = string.Empty;

this.Rate = 0.0M;

}

public Customer(int id, string name, Decimal rate)

1

this.ID = id; this. Name = name; this.Rate = rate;

}

// Номер public int ID

{

get { return id; ) set { id = value; )

}

11 Имя

public string Name

{

get { return name; } set { name = value; )

}

// Стоимость

public Decimal Rate {

get { return rate; } set { rate = value; }

}

)

Итак, свойство Text первого компонента привязано к полю id, а два других компонента привязаны к одному и тому же свойству Name. Запустив приложение, можно увидеть, что, во-первых, в каждом из текстовых полей отображается привязанное к нему свойство, и во-вторых, при изменении текстового поля textBox2 эти изменения отображаются в компоненте textBox3! Это происходит из-за того, что оба этих компонента привязаны к одному полю, а значит, при изменении значения textBox2 происходит изменение самого поля, что, в свою очередь, вызывает изменение значения textBox3: textBox2 —? поле Name —? textBox3

Сложная привязка данных позволяет привязать список объектов к некоторому компоненту, предназначенному для отображения (и, возможно, редактирования) этого списка. Например, компонент dataGridViewi мы привяжем к списку объектов Customer:

BindingList<Customer> list – new BindingList<Customer>(); list.Addfnew Customer(0, "Mr. Zero", 10.0M)); list.Addfnew Custamer{l, "Mr. One" , 15.0M)); list.Add(new Customer{2, "Mr. Two" , 20.0M)); this.dataGridViewi.DataSource = list;

Запустив приложение, мы увидим, что список отображается в сетке данных.

Привяжем еще компонент textBox4 к тому же списку:

this.textBox4.DataBindings.Add{"Text", list, "Name", true);

Теперь, перемещаясь по списку, мы можем видеть, как меняется значение в textBox4. Другими словами, мы создали связку между простой и сложной привязками данных.

И еще два небольших теста. Для компонента textBoxS мы сначала создадим класс привязки, а затем уже выполним саму привязку:

Binding rateBinding = new Binding("Text", list, "Rate", true);

rateBinding.FormatString = "c";

this.textBox5.DataBindings.Add(rateBinding);

Свойство FormatString позволяет задать формат отображения данных. При необходимости более сложной обработки отображаемых и вводимых данных можно воспользоваться событиями Format и Parse:

Binding nameBinding – new Binding("Text", list, "Name"); nameBinding.Format += new ConvertEventHandler(nameBinding_Format); nameBinding.Parse += new ConvertEventHandler (nameBinding__Parse) ; this.textBox6.DataBindings.Add(nameBinding);

void nameBinding_Parse(object sender, ConvertEventArgs e)

{

string value – e.Value.ToStringO ; if (value.IndexOf("Имя: ") ==0)

e.Value – e.Value.ToString().Remove(0, 5);

}

void nameBinding_Format(object sender, ConvertEventArgs e) {

e.Value = string.Format("Имя: (0)", e.Value);

1

Событие Format вызывается при необходимости отобразить значение, а событие parse— при попытке получить реальное значение из введенных пользователем данных. Вообще, класс Binding имеет множество полезных свойств, но описывать их здесь я не буду. Для этого существует множество справочной литературы.

В конце раздела я покажу, как получить ссылки на объекты, которые я описывал ранее:

BindingManagerBase managerBase =

this.textBoxl.BindingContext[customer, "ID"]; PropertyManager propertyManager =

(PropertyManager)this.textBoxl.BindingContext[customer]; CurrencyManager currencyManager =

(CurrencyManager)this.dataGridViewl.BindingContext[list];

Например, для управления положением указателя данных можно использовать такой код:

private void buttonl_Click(object sender, EventArgs e)

{

if (currencyManager.Position < currencyManager.Count – 1)

{

currencyManager.Position++;

}

}

private void button2_Click(object sender, EventArgs e) {

if (currencyManager.Position > 0)

{

currencyManager.Position—;

}

}

Далее я расскажу о стандартных свойствах привязки данных.

Литература:

Агуров П. В. C#. Разработка компонентов в MS Visual Studio 2005/2008. – СПб.: БХВ-Петербург, 2008. — 480 е.: ил.

По теме:

  • Комментарии