|
|
Побродим по DataSet
Побродим по DataSet
Новое всегда познается в сравнении и, не сделав что-нибудь своими руками
с использованием новых технологий, не сможешь сравнить их с тем, что знал
раньше. Вот так вот и мы - получив в руки .NET Framework или VS.NET пытаемся
сделать что-то, что раньше уже делали с помощью C++, Delphi или Visual
Basic. Сейчас я попытаюсь рассказать как можно решить такую, тривиальную,
на первый взгляд, задачу, как создание формы, в которой есть DataGrid
для перемещения по таблице данных и поля ввода для редактирования. Также
я покажу как делать навигационные контролы для перемещения по DataGrid.
Итак, начнем. Работать будем в VS.NET Beta 1, которое, я надеюсь, есть
у многих (если не у всех) вас.
Создадим новый проект WinApp и назовем его DBNav1 (ибо будут еще и 2,
и 3, а может и еще :). Будем использовать данные из базы pubs, которая
входит в стандартную поставку MS SQL, конкретно из таблицы authors. Итак
бросаем на форму компоненты SQLDataSetCommand, подключаем ее к базе pubs,
а в SQL запросе пишем select * from pubs. Затем генерим DataSet (щелчок
правой кнопкой мыши по SQLDataSetCommand1 и выбираем Generate DataSet)
и называем ее dsAuthors. Генерим также методы (щелчок правой кнопкой мыши
по SQLDataSetCommand1 и выбираем Generate Methods). Теперь создадим интерфейс
пользователя. Бросаем на форму DataGrid и необходимое количество TextBoxов.
По DataGrid мы будем перемещаться, при этом в TextBoxах нам необходимо
будет получить данные из записи, выбранной в DataGrid. Привязываем наши
Grid и TextBoxы к данным. Вставляем вызов FillDataSet() (один из сгенерированных
нами методов) в конце конструктора формы и считаем, что первый этап нашей
работы закончен :. Компилируем проект и запускаем его на выполнение. Взять
полученный проект можно здесь.
(Естественно он у вас сразу не заработает. Для того чтобы вы смогли запустить
этот пример измените параметры подключения в SQLConnection строке 280.)
И что же мы видим??? А видим мы то, что хоть и можем мы перемещаться по
DataGrid, но данные в контролах не меняются. Т.е. нет никакой синхронизации.
Что ж, попробуем ее добиться…
Попробуем разобраться, как данные попадают в контролы. Для этого внимательно
посмотрим на код InitializeComponent, особо обращая внимание на строки,
в которых происходит привязывание данных к контролам. Я не буду долго
вас водить по пути, через который прошел сам, а сразу же покажу решение:
- Отсоединить от DataSet все контролы, кроме DataGrid (там все как раз
таки работает без вопросов).
- Вручную связать контролы с соответствующими полями DataSet с помощью
метода Add коллекции Bindings контрола.
Вот функция, вызов которой я вставил в конструктор вместо вызова FillDataSet:
private void DoDataBind()
{
FillDataSet(dsAuthors1);
textBox1.Bindings.Add("Text", dsAuthors1.Tables["authors"], "au_lname");
textBox2.Bindings.Add("Text", dsAuthors1.Tables["authors"], "au_fname");
textBox3.Bindings.Add("Text", dsAuthors1.Tables["authors"], "phone");
textBox4.Bindings.Add("Text", dsAuthors1.Tables["authors"], "address");
textBox5.Bindings.Add("Text", dsAuthors1.Tables["authors"], "city");
textBox6.Bindings.Add("Text", dsAuthors1.Tables["authors"], "state");
textBox7.Bindings.Add("Text", dsAuthors1.Tables["authors"], "zip");
checkBox1.Bindings.Add("Checked", dsAuthors1.Tables["authors"], "contract");
} |
Компилируем получившееся, запускаем и... О, чудо! Работает! : Взять проект
DBNav2 можно здесь.
Теперь попробуем сделать все-таки что-то похожее на панель навигации от
MS Access. Т.е. 4 кнопки (MoveFirst, MovePrev, MoveNext, MoveLast) и строку
сообщения типа "Record N of M".
После долгих поисков я обнаружил объект ListManager. В MSDN про него написано
следующее: "ListManager - центральный объект для синхронизации связанных
с данными контролов (показывать данные одной и той же записи)". Кроме этого
данный объект обладает двумя очень интересными для нас свойствами. Это Count
- кол-во записей в ListManager и Position - указатель на ту самую "текущую
запись", который нам нужен для осуществления перемещения по записям. И что
важно - свойство Position предназначено и для чтения, и для записи, т.е.
устанавливая Position в целое, лежащее между 1 и Count мы изменяем позицию
текущей записи.
Применим данные теоретические выкладки на практике. Положим на форму 4 Button,
пару Label и 1 TextBox. Добавим в конец нашего метода DoDataBind следующие
строки:
myLM = this.BindingManager[dsAuthors1.Tables["authors"]];
myLM.CurrentChanged += new System.EventHandler(ListManager_PositionChanged);
txtCurrRec.Text = (myLM.Position + 1).ToString();
lblCnt.Text = "of" + myLM.Count.ToString(); |
а в раздел описания свойств нашей формы след. Строку:
private ListManager myLM; |
(у меня она находится в 54 строке).
Теперь напишем события для наших кнопок. Все они похожи - при нажатии на
кнопку изменяется значение свойства Position объекта myLM. Также добавим
событие изменения Position дабы контролировать вывод номера текущей записи
и событие изменения значения поля txtCurrPos для перемещения на указанную
в этом поле запись:
protected void txtCurrPos_KeyDown(object sender, System.WinForms.KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
try
{
int pos = txtCurrPos.Text.ToInt32();
if ((pos > 0) && (pos <= myLM.Count))
{
myLM.Position = pos - 1;
}
else
{
myLM.Position = 0;
txtCurrPos.Text = "1";
}
}
catch
{
myLM.Position = 0;
txtCurrPos.Text = "1";
}
}
}
protected void btnLast_Click (object sender, System.EventArgs e)
{
myLM.Position = myLM.Count - 1;
}
protected void btnNext_Click (object sender, System.EventArgs e)
{
if (myLM.Position != myLM.Count - 1)
{
myLM.Position++;
}
}
protected void btnPrev_Click (object sender, System.EventArgs e)
{
if (myLM.Position > 0)
{
myLM.Position--;
}
}
protected void btnFirst_Click (object sender, System.EventArgs e)
{
myLM.Position = 0;
} |
Вот и все. На этом процесс построения нашего приложения с Accessоподобным
интерфейсом можно считать завершенным. Исходники проекта DBNav3 можно взять
здесь.
Далі буде.
Dimon aka Manowar
|