Студопедия

Главная страница Случайная страница

Разделы сайта

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






Благодарности 22 страница






Сейчас мы реализуем эту часть приложения, отвечающую за добавление новых узлов в дерево.

Прежде всего, создайте обработчик событий для строки Add контекстного меню contextMenu1, щелкнув его дважды левой клавишей мыши. Отредактируйте исходный текст обработчика следующим образом:

private void menuItem1_Click(object sender, System.EventArgs e)
{
if(treeView1.SelectedNode! = null)
{
int id = (int)treeView1.SelectedNode.Tag;
AddNode(id);
UpdateTree();
}
else
{
// Пустой список
if(treeView1.Nodes.Count == 0)
{
AddNode(0);
UpdateTree();
}
}
}

При самом первом запуске приложения и пустой базе данных в дереве treeView1 не выделено ни одного элемента, т.к. их там попросту нет. Соответственно, количество узлов дерева treeView1.Nodes.Count равно нулю. В этом случае наше приложение вызывает два метода:

AddNode(0);
UpdateTree();

Метод AddNode, определенный в нашем приложении, создает узел дерева. В качестве единственного параметра этому методу нужно передать идентификатор родительского узла. Так как в первый раз мы создаем корневой узел, то передаем методу AddNode нулевое значение.

Что же касается метода UpdateTree, то он тоже определен в нашем приложении. Его задачей является наполнение окна дерева treeView1 содержимым таблицы Tree базы данных Articles. Мы вызываем этот метод всякий раз после внесения изменений в структуру дерева (т.е. после добавления или удаления узлов дерева).

Для того чтобы содержимое дерева отображалось сразу осле запуска приложения, мы добавили вызов метода UpdateTree в конструктор класса Form1:

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
UpdateTree();
}

Методы AddNode и UpdateTree мы рассмотрим в деталях позже, а пока вернемся к обработчику событий menuItem1_Click, созданному нами для строки Add контекстного меню.

В том случае, если в дереве есть узлы, и пользователь выделил какой-либо узел левой клавишей мыши или при помощи клавиатуры, наш обработчик событий menuItem1_Click выполняет следующие действия:

if(treeView1.SelectedNode! = null)
{
int id = (int)treeView1.SelectedNode.Tag;
AddNode(id);
UpdateTree();
}

Вначале он извлекает из свойства treeView1.SelectedNode.Tag идентификатор строки таблицы Tree, соответствующий выделенному узлу. Этот идентификатор записывается в данное свойство методом UpdateTree в процессе построения дерева.

Заметим, что данный идентификатор обозначает узел, являющийся родительским по отношению к создаваемому узлу. Обработчик событий menuItem1_Click передает этот идентификатор методу AddNode, а затем перерисовывает обновленное дерево методом UpdateTree:

AddNode(id);
UpdateTree();

Метод AddNode

Создайте в классе Form1 метод AddNode. Как мы только что говорили, этот метод предназначен для создания нового узла в дереве заголовков статей. Он не только добавляет новый узел в окно элемента управления treeView1, но и создает все необходимые записи в базе данных Articles.

Ниже мы привели полный исходный текст метода AddNode:

public void AddNode(int id)
{
Form2 dialog = new Form2();
if(DialogResult.Yes == dialog.ShowDialog())
{
sqlConnection1.Open();
try
{
SqlCommand cmd = new SqlCommand(" sp_InsertNode",
sqlConnection1);
cmd.CommandType = CommandType.StoredProcedure;

SqlParameter param = cmd.Parameters.Add(" RETURN_VALUE",
SqlDbType.Int);

param.Direction = ParameterDirection.ReturnValue;

cmd.Parameters.Add(" @parent_id", SqlDbType.Int).Value = id;
cmd.Parameters.Add(" @title", SqlDbType.VarChar).Value =
dialog.Title;
cmd.Parameters.Add(" @weight", SqlDbType.Int).Value =
dialog.Weight;

cmd.ExecuteNonQuery();

int tree_id = (int)cmd.Parameters[" RETURN_VALUE" ].Value;

cmd = new SqlCommand(" sp_InsertDocument", sqlConnection1);
cmd.CommandType = CommandType.StoredProcedure;

param = cmd.Parameters.Add(" RETURN_VALUE", SqlDbType.Int);
param.Direction = ParameterDirection.ReturnValue;

cmd.Parameters.Add(" @tree_id", SqlDbType.Int).Value = tree_id;
cmd.Parameters.Add(" @document", SqlDbType.VarChar).Value =
dialog.Document;

cmd.ExecuteNonQuery();

int document_id = (int)cmd.Parameters[" RETURN_VALUE" ].Value;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, " Ошибка");
}
sqlConnection1.Close();
}
}

Займемся описанием этого исходного текста.

Диалоговое окно для ввода данных добавляемого узла

В самом начале работы метод AddNode отображает на экране диалоговое окно, показанное на рис. 9-43. Вам нужно будет создать форму для данного окна, но этим мы займемся позже.

Окно создается обычным образом с помощью конструктора. Если пользователь закрыл диалоговое окно с помощью кнопки Сохранить, метод AddNode извлекает данные, введенный пользователем, и добавляет их в таблицы базы данных Articles:

Form2 dialog = new Form2();
if(DialogResult.Yes == dialog.ShowDialog())
{

}

Открытие и закрытие соединения с базой данных

Для добавления данных, прежде всего, открывается соединение с базой данных:

sqlConnection1.Open();

Все дальнейшие операции выполняются в теле оператора try-catch, что позволяет перехватывать ошибки и отображать текст сообщений об ошибках на экране:

try
{

}
catch(Exception ex)
{
MessageBox.Show(ex.Message, " Ошибка");
}

sqlConnection1.Close();

После обновления содержимого базы данных метод AddNode закрывает соединение с базой данных.

Использование хранимых процедур

Теперь мы займемся описанием кода, добавляющего новые записи в базу данных. Этот код интересен тем, что мы не будем встраивать в него команды SQL, а воспользуемся механизмом хранимых процедур сервера Microsoft SQL Server.

Прежде всего, наша программа вызывает хранимую процедуру sp_InsertNode, предназначенную для добавления новой строки в таблицу Tree, хранящую структуру дерева. Напомним, что этой процедуре нужно передать через входные параметры идентификатор родительского узла @parent_id, заголовок статьи @title и вес сортировки @weight.

Вызов хранимой процедуры начинается с создания объекта класса SqlCommand:

SqlCommand cmd = new SqlCommand(" sp_InsertNode", sqlConnection1);

Далее программа должна задать тип команды в свойстве CommandType в виде константы CommandType.StoredProcedure:

cmd.CommandType = CommandType.StoredProcedure;

Это означает, что команда содержит не строку SQL, а имя хранимой процедуры.

Параметры хранимых процедур

На следующем этапе необходимо добавить параметры хранимой процедуры. Наша хранимая процедура sp_InsertNode имеет три входных и один выходной параметр.

Через выходной параметр со специальным именем RETURN_VALUE хранимая процедура возвращает идентификатор добавленной строки:

SqlParameter param = cmd.Parameters.Add(" RETURN_VALUE",
SqlDbType.Int);

В качестве первого параметра методу Add передается имя параметра хранимой процедуры, а в качестве второго — тип данных, соответствующих этому параметру.

Чтобы указать, что этот параметр является выходным, мы записываем константу ParameterDirection.ReturnValue в свойство параметра с именем Direction:

param.Direction = ParameterDirection.ReturnValue;

Если этого не сделать, то по умолчанию параметр будет входным.

Вот как мы указываем входные параметры для хранимой процедуры sp_InsertNode:

cmd.Parameters.Add(" @parent_id", SqlDbType.Int).Value = id;
cmd.Parameters.Add(" @title", SqlDbType.VarChar).Value = dialog.Title;
cmd.Parameters.Add(" @weight", SqlDbType.Int).Value = dialog.Weight;

Обратите внимание на то, что тип числовых данных указан как SqlDbType.Int, а тип строчных данных — как SqlDbT ype.VarChar.

Параметру хранимой процедуры @parent_id мы присваиваем значение идентификатора родительского узла, который передается при вызове методу AddNode. Что же касается параметров @title и @weight, то для их инициализации мы извлекаем значения из свойств Title и Weight, определенных нами в классе Form2 диалогового окна ввода данных узла (рис. 9-43).

Запуск хранимой процедуры

Для запуска хранимой процедуры на выполнение мы вызываем метод ExecuteNonQuery:

cmd.ExecuteNonQuery();

Если у хранимой процедуры имеются параметры (как в нашем случае), то их необходимо подготовить. Иначе при выполнении метода ExecuteNonQuery возникнет исключение.

Получение значений выходных параметров

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

Вот как мы извлекаем значение, возвращаемое хранимой процедурой sp_InsertNode:

int tree_id = (int)cmd.Parameters[" RETURN_VALUE" ].Value;

Напомним, что наша хранимая процедура возвращает идентификатор узла, добавленного в таблицу Tree. Этот идентификатор понадобится нам в дальнейшем для инициализации ячейки внешнего ключа таблицы Documents, ссылающейся на таблицу Tree.

Добавление текста документа

Для добавления текста документа, извлеченного из свойства dialog.Document диалогового окна класса Form2 мы вызываем хранимую процедуру sp_InsertDocument:

cmd = new SqlCommand(" sp_InsertDocument", sqlConnection1);
cmd.CommandType = CommandType.StoredProcedure;

Эта процедура имеет один выходной параметр и два входных:

param = cmd.Parameters.Add(" RETURN_VALUE", SqlDbType.Int);
param.Direction = ParameterDirection.ReturnValue;

cmd.Parameters.Add(" @tree_id", SqlDbType.Int).Value = tree_id;
cmd.Parameters.Add(" @document", SqlDbType.Text).Value =
dialog.Document;

Выходной параметр получает получить идентификатор новой строки в таблице Documents. Мы извлекаем его только для примера, но в приложении не используем. Что же касается входных параметров, то хранимой процедуре sp_InsertDocument передается идентификатор узла @tree_id обновляемой статьи, а также текст статьи @document.

Обратите внимание, что параметр @document имеет тип SqlDbType.Text.

Хранимая процедура sp_InsertDocument запускается при помощи метода ExecuteNonQuery, после чего извлекается результат ее выполнения:

cmd.ExecuteNonQuery();
int document_id = (int)cmd.Parameters[" RETURN_VALUE" ].Value;

Диалоговая форма редактирования документа

Для того чтобы создать диалоговую форму редактирования документа, Вам нужно добавить к проекту еще одну экранную форму Form2. Соответствующие процедуры были подробно описаны в 5 главе нашей книги.

Для того чтобы программа могла инициализировать поля формы, а также получать значения, введенные в ней пользователем, необходимо создать в классе Form2 свойства Title, Weight и Document. Каждое из этих свойств должно содержать методы доступа set и get.

Свойство Title

Свойство Title должно быть определено следующим образом:

public string Title
{
get
{
return textBox1.Text;
}
set
{
textBox1.Text = value;
}
}

Предполагается, что это свойство связано с полем редактирования заголовка статьи textBox1.

Свойство Weight

Свойство Weight предназначено для ввода и редактирования веса сортировки статьи. вес сортировки представляет собой числовое значение. Для его редактирования мы использовали элемент управления класса NumericUpDown.

Вот исходный текст методов доступа свойства Weight:

public int Weight
{
get
{
return (int)numericUpDown1.Value;
}
set
{
numericUpDown1.Value = value;
}
}

Свойство Document

Текст статей мы создаем и редактируем при помощи элемента управления richTextBox1. Вот исходный текст методов доступа свойства Document, с помощью которого наша программа может отображать исходный текст статьи, а также загружать отредактированный вариант статьи:

public string Document
{
get
{
return richTextBox1.Text;
}
set
{
richTextBox1.Text = value;
}
}

Построение дерева

Для построения дерева заголовков статей в окне элемента управления TreeView в нашем приложении определен метод UpdateTree, на который мы уже ссылались ранее, а также метод CreateNodes.

Метод UpdateTree

Метод UpdateTree считывает структуру дерева из базы данных Articles и отображает ее в окне элемента управления treeView1 класса TreeView.

Вот исходный текст этого метода:

public void UpdateTree()
{
dataSet11.Clear();
sqlDataAdapter1.Fill(dataSet11);

treeView1.Nodes.Clear();
CreateNodes(0, (TreeNode)null);
treeView1.ExpandAll();
}

Получив управление, метод UpdateTree очищает набор данных dataSet11, а затем наполняет его из таблицы Tree базы данных Aticles, пользуясь для этого адаптером sqlDataAdapter1 и методом Fill.

На следующем этапе метод UpdateTree удаляет все элементы из дерева treeView1.

Заполнение дерева treeView1 содержимым набора данных dataSet11 осуществляется методом CreateNodes. Далее все узлы заполненного дерева раскрываются, для чего программа вызывает метод treeView1.ExpandAll.

Метод CreateNodes

Теперь нам нужно изучить метод CreateNodes, который создает в дереве treeView1 узел, соответствующий одной статье. Ниже мы привели исходный текст этого метода:

public void CreateNodes(int iParent, TreeNode pNode)
{
DataView dvwData = new DataView(dataSet11.Tables[0]);
dvwData.RowFilter = " [parent_id] = " + iParent;

foreach(DataRowView Row in dvwData)
{
int id = Int32.Parse(Row[" id" ].ToString());

if(pNode == null)
{
TreeNode zNode = treeView1.Nodes.Add(Row[" title" ].ToString() +
" (" + Row[" weight" ].ToString() + ")");
zNode.Tag = id;

CreateNodes(id, zNode);
}
else
{
if(id == iParent)
{
return;
}
TreeNode zNode = pNode.Nodes.Add(Row[" title" ].ToString() +
" (" + Row[" weight" ].ToString() + ")");

zNode.Tag = id;

CreateNodes(id, zNode);
}
}
}

Метод CreateNodes имеет два параметра.

Через первый параметр методу передается идентификатор узла, родительского по отношению к добавляемому узлу. Если создается корневой узел, то значение этого параметра равно нулю.

Второй параметр используется для передачи ссылки на родительский узел дерева treeView1, который является объектом класса TreeNode. При создании корневого узла этот параметр должен иметь значение null.

Как работает метод CreateNodes?

Прежде всего, он создает представление (view) таблицы dvwData, хранящейся в наборе данных dataSet11. Это представление включает в себя подмножество строк таблицы, столбец parent_id которых содержит идентификатор родительского узла, переданного методу CreateNodes в качестве первого параметра. Иными словами, здесь происходит отбор дочерних узлов заданного родительского узла.

Вот как создается это представление:

DataView dvwData = new DataView(dataSet11.Tables[0]);
dvwData.RowFilter = " [parent_id] = " + iParent;

В свойстве dvwData.RowFilter мы указываем нужное нам условие отбора строк в самой первой (и единственной) таблице набора данных dataSet11.

После того как все нужные строки будут отобраны, запускается цикл по всем строкам полученного представления:

foreach(DataRowView Row in dvwData)
{

}

Внутри этого цикла мы извлекаем идентификатор каждой строки id и сохраняем ее в одноименной переменной. Для преобразования извлеченного значения в число мы используем метод Int32.Parse:

int id = Int32.Parse(Row[" id" ].ToString());

Дальнейшие действия, выполняемые нашей программой, зависят от значения второго параметра метода CreateNodes.

Вот как добавляется корневой узел дерева:

if(pNode == null)
{
TreeNode zNode = treeView1.Nodes.Add(Row[" title" ].ToString() +
" (" + Row[" weight" ].ToString() + ")");

zNode.Tag = id;
CreateNodes(id, zNode);
}

Здесь мы с помощью метода treeView1.Nodes.Add добавляем в дерево treeView1 новый элемент. В качестве текстовой строки, отображаемой в окне дерева, мы используем заголовок статьи, извлеченный из столбца title текущей извлеченной строки. К этому заголовку мы дописываем в круглых скобках значение веса сортировки, взятого из столбца weight.

Далее наша программа записывает в свойство Tag идентификатор узла дерева, взяв его из столбца id. Пользуясь этим свойством, приложение сможет однозначно сопоставить элементы дерева, выделенные пользователем в окне элемента управления treeView1, и строки таблицы Tree, хранящей информацию об узлах дерева в базе данных Microsoft SQL Server.

И, наконец, метод CreateNodes вызывает сам себя рекурсивно для добавления в дерево всех узлов, дочерних для только что добавленного элемента. Обратите внимание, что теперь в качестве второго параметра этому методу передается ссылка на только что созданный узел дерева zNode.

Теперь настало время рассмотреть действия метода CreateNodes при рекурсивном вызове, когда значение второго параметра не равно null.

Прежде всего, в этом случае метод проверяет условие выхода из рекурсии:

if(id == iParent)
{
return;
}

Если идентификатор узла равен идентификатору родительского узла, работа метода завершается оператором return.

В противном случае мы создаем узел дерева, записывая идентификатор узла id в свойство zNode.Tag:

TreeNode zNode = pNode.Nodes.Add(Row[" title" ].ToString() +
" (" + Row[" weight" ].ToString() + ")");

zNode.Tag = id;

Далее следует рекурсивный вызов метода CreateNodes:

CreateNodes(id, zNode);

Редактирование узла дерева

Итак, мы рассмотрели процедуру создания узлов дерева, а также методы, применяющиеся для отображения дерева в окне элемента управления TreeView. Теперь нашей задачей будет добавить в приложение код, позволяющий редактировать содержимое узла, выделенного пользователем в окне дерева.

Обработчик событий меню Edit

Когда пользователь выделяет узел дерева, а затем щелкает его правой клавишей мыши и выбирает из контекстного меню строку Edit, управление передается обработчику событий menuItem3_Click. Вы должны создать этот обработчик в следующем виде:

private void menuItem3_Click(object sender, System.EventArgs e)
{
// Пустой список
if(treeView1.Nodes.Count! = 0)
{
int id = (int)treeView1.SelectedNode.Tag;

Form2 dialog = new Form2();

sqlConnection1.Open();

SqlDataReader myReader;
string strCmd = String.Format(
" SELECT document FROM Documents WHERE tree_id = {0}", id);
SqlCommand cmd = new SqlCommand(strCmd, sqlConnection1);
myReader = cmd.ExecuteReader();

if(myReader.Read())
{
dialog.Document = myReader.GetString(0).ToString();
}
myReader.Close();

sqlGetNodeCommand.Parameters[" @id" ].Value = id;
myReader = sqlGetNodeCommand.ExecuteReader();

if(myReader.Read())
{
dialog.Title = myReader.GetString(2).ToString();
dialog.Weight = myReader.GetInt32(3);

if(DialogResult.Yes == dialog.ShowDialog())
{
try
{
sqlUpdateNodeCommand.Parameters[" @id" ].Value = id;
sqlUpdateNodeCommand.Parameters[" @title" ].Value =
dialog.Title;
sqlUpdateNodeCommand.Parameters[" @weight" ].Value =
dialog.Weight;

myReader.Close();

sqlUpdateNodeCommand.ExecuteNonQuery();

cmd = new SqlCommand(" sp_UpdateDocument",
sqlConnection1);

cmd.CommandType = CommandType.StoredProcedure;

cmd.Parameters.Add(" @tree_id", SqlDbType.Int).Value = id;
cmd.Parameters.Add(" @document", SqlDbType.VarChar).Value=
dialog.Document;

cmd.ExecuteNonQuery();

richTextBox1.Text = dialog.Document;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, " Ошибка");
}
}

sqlConnection1.Close();
UpdateTree();
}
}
}

Получив управление, обработчик событий menuItem3_Click, прежде всего, проверяет, есть ли какие-либо элементы в окне дерева:

if(treeView1.Nodes.Count! = 0)
{

}

Если дерево пустое, обработчик возвращает управление, не предпринимая никаких действий.

Извлечение идентификатора редактируемого узла

В том случае, когда в дереве есть узлы, обработчик получает идентификатор выделенного узла, извлекая его из свойства treeView1.SelectedNode.Tag:

int id = (int)treeView1.SelectedNode.Tag;

Напомним, что этот идентификатор равен содержимому столбца id строки таблицы Tree, описывающей данный узел. Этот идентификатор записывается в свойство treeView1.SelectedNode.Tag во время заполнения окна элемента управления treeView1.

Идентификатор id потребуется нам для извлечения из таблицы Tree информации об узле дерева, подлежащей редактированию.

Для редактирования мы создаем форму класса Form2:

Form2 dialog = new Form2();

Это та же самая форма, которую мы использовали для создания новых узлов дерева (рис. 9-43).

Извлечение данных редактируемого узла дерева

Далее нам нужно заполнить поля формы текущей информацией из таблиц Tree и Document, соответствующей данному узлу с идентификатором id. С этой целью мы открываем соединения с базой данных sqlConnection1 и создаем объект класса SqlDataReader:

sqlConnection1.Open();
SqlDataReader myReader;

Получение текст редактируемой статьи

На первом шаге нам нужно создать команду SQL класса SqlCommand, с помощью которой мы могли бы извлечь текст редактируемой статьи из таблицы Documents. При этом нам необходимо найти в этой таблице такую строку, для которой в столбце tree_id хранилось бы значение, равное идентификатору редактируемого узла дерева id.

Необходимую команду SQL мы создаем «на лету», формируя соответствующую текстовую строку с помощью класса String.Format:

string strCmd = String.Format(
" SELECT document FROM Documents WHERE tree_id = {0}", id);

SqlCommand cmd = new SqlCommand(strCmd, sqlConnection1);

После выполнения команды методом ExecuteReader обработчик событий извлекает текст документа методом myReader.GetString, а затем сохраняет его в свойстве dialog.Document диалогового окна редактирования узлов дерева:

myReader = cmd.ExecuteReader();

if(myReader.Read())
{
dialog.Document = myReader.GetString(0).ToString();
}

myReader.Close();

Далее обработчик закрывает объект SqlDataReader, чтобы подготовить его к выполнению новой команды.

Извлечение заголовка и веса сортировки

Для того чтобы извлечь заголовок редактируемой статьи и вес сортировки, мы создали команду sqlGetNodeCommand. Ниже приведен текст команды SQL, который нужно записать в свойство CommandText объекта sqlGetNodeCommand:

SELECT id, parent_id, title, weight FROM dbo.Tree WHERE (id = @id)

Через параметр @id команде передается идентификатор узла дерева, для которого нужно извлечь информацию из таблицы Tree:

sqlGetNodeCommand.Parameters[" @id" ].Value = id;

Далее подготовленная команда запускается на выполнение с помощью метода ExecuteReader:

myReader = sqlGetNodeCommand.ExecuteReader();

Если программа нашла в таблице Tree нужный нам узел, то заголовок статьи и вес сортировки этого узла записывается, соответственно, в свойства dialog.Title и dialog.Weight диалогового окна редактирования:

if(myReader.Read())
{
dialog.Title = myReader.GetString(2).ToString();
dialog.Weight = myReader.GetInt32(3);

}

Обновление информации узла в базе данных

Когда пользователь завершает редактирование данных в форме, показанной на рис. 9-43, при помощи кнопки Сохранить, метод dialog.ShowDialog возвращает значение DialogResult.Yes. В этом случае обработчик событий menuItem3_Click обновляет информацию об узле в базе данных:

if(DialogResult.Yes == dialog.ShowDialog())
{
try
{
// Обновление базы данных

}
catch(Exception ex)
{
MessageBox.Show(ex.Message, " Ошибка");
}
}

Обновление выполняется с помощью команды sqlUpdateNodeCommand и хранимой процедуры sp_UpdateDocument, исходный текст которой мы уже приводили ранее в этой главе.

Свойство CommandText команды sqlUpdateNodeCommand должно быть установлено следующим образом:

UPDATE dbo.Tree SET title = @title, weight = @weight WHERE (id = @id)

Команде sqlUpdateNodeCommand нужно передать три параметра:

sqlUpdateNodeCommand.Parameters[" @id" ].Value = id;
sqlUpdateNodeCommand.Parameters[" @title" ].Value = dialog.Title;
sqlUpdateNodeCommand.Parameters[" @weight" ].Value = dialog.Weight;

Первый из этих параметров задает идентификатор обновляемого узла, второй — новый заголовок статьи, и третий — новый вес сортировки.

Команда выполняется обычным образом с помощью метода ExecuteNonQuery:

myReader.Close();
sqlUpdateNodeCommand.ExecuteNonQuery();

Перед выполнением этой команды мы закрываем ненужный нам больше объект myReader.

Как мы уже говорили, текст статьи обновляется в таблице Documents при помощи хранимой процедуры sp_UpdateDocument:

cmd = new SqlCommand(" sp_UpdateDocument", sqlConnection1);
cmd.CommandType = CommandType.StoredProcedure;

Для этой хранимой процедуры необходимо задать два параметра:

cmd.Parameters.Add(" @tree_id", SqlDbType.Int).Value = id;
cmd.Parameters.Add(" @document", SqlDbType.VarChar).Value =
dialog.Document;

Первый из этих параметров задает идентификатор обновляемой статьи, а второй — новый текст статьи.

После подготовки параметров хранимая процедура sp_UpdateDocument запускается на выполнение при помощи метода ExecuteNonQuery:

cmd.ExecuteNonQuery();

С целью демонстрации различных методов обновления базы данных мы искусственно разделили процесс обновления таблиц Tree и Documents. Первая из этих таблиц выполняется при помощи команды SQL, созданной в виде объекта класса SqlCommand, а вторая — с помощью хранимой процедуры sp_UpdateDocument.

В реальных приложениях имеет смысл использовать какой-то один способ, обновляя базы данных, например, в хранимой процедуре. В качестве самостоятельного упражнения измените хранимую процедуру sp_UpdateDocument таким образом, чтобы она модифицировала обе таблицы. После этого уберите из приложения код, обновляющий таблицу Tree при помощи команды sqlUpdateNodeCommand.

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

richTextBox1.Text = dialog.Document;

Далее этот обработчик закрывает соединение с базой данных и перерисовывает дерево:

sqlConnection1.Close();
UpdateTree();

Удаление узла дерева

Чтобы удалить статью, пользователь должен выделить его заголовок в окне дерева, затем щелкнуть этот заголовок правой клавишей мыши и выбрать из контекстного меню строку Delete.

В результате этих действий управление будет передано обработчику событий menuItem2_Click. Создайте его в следующем виде:

private void menuItem2_Click(object sender, System.EventArgs e)
{
if(treeView1.SelectedNode! = null)
{
int id = (int)treeView1.SelectedNode.Tag;
DeleteNode(id);
UpdateTree();
}
}

Если в окне дерева есть узлы, выделенные пользователем (т.е. если значение свойства treeView1.SelectedNode не равно null), то обработчик событий menuItem2_Click получает идентификатор узла, подлежащего к удалению. Этот идентификатор считывается из свойства treeView1.SelectedNode.Tag, куда он был записан во время заполнения дерева.

Далее узел удаляется методом DeleteNode, определенным в нашем приложении, после чего окно дерева обновляется при помощи метода UpdateTree.

Ниже мы привели исходный текст метода DeleteNode:

public void DeleteNode(int id)
{
SqlDataReader myReader;

sqlConnection1.Open();
try
{
sqlFindChildsCommand.Parameters[" @parent_id" ].Value = id;
myReader = sqlFindChildsCommand.ExecuteReader();
if(! myReader.Read())
{
myReader.Close();

sqlDeleteRowCommand1.Parameters[" @id" ].Value = id;
sqlDeleteRowCommand1.ExecuteNonQuery();

string strCmd = String.Format(
" DELETE FROM Documents WHERE tree_id = {0}", id);
SqlCommand cmd = new SqlCommand(strCmd, sqlConnection1);
cmd.ExecuteNonQuery();

richTextBox1.Text = " ";
}
else
{
myReader.Close();
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, " Ошибка");
}
sqlConnection1.Close();
}

Получив управление, этот метод создает объект myReader класса SqlDataReader и открывает соединение с базой данных:






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.