Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 [2]  Все   Вниз
  Печать  
Автор Тема: Переименование Itema в TreeView  (Прочитано 58545 раз)
0 Пользователей и 3 Гостей смотрят эту тему.
Alf
Гость
« Ответ #30 : 14-04-2004 06:44 » 

Dimyan, мой тебе совет - поставь точку останова в процедуре и пройди ее в пошаговом режиме. Самый лучший способ постичь рекурсию.
Записан
Dimyan
Гость
« Ответ #31 : 14-04-2004 08:50 » 

Цитата: Alf
Dimyan, мой тебе совет - поставь точку останова в процедуре и пройди ее в пошаговом режиме. Самый лучший способ постичь рекурсию.

Обязательно

Цитата
4. Считывание всех узлов из базы данных - вынужденная мера, поскольку соединение Connection может иметь только один выполняющийся DataReader в данный момент времени. Поэтому приходится считываьт их все разом и освобождать DataReader для следующего рекурсивного вызова.

Я пока шибко не разобрался, может я не прав, но мне кажется что при считивании всей информации из базы она ведь начинает храниться в памяти, не будет ли это катострафично при большом обьеме базы?
Записан
Alf
Гость
« Ответ #32 : 14-04-2004 09:19 » 

Dimyan, эта информация все равно вынуждена сидеть в памяти, иначе ты дерево не построишь. А несколько лишних байт на узел вряд ли будут очень накладны. У тебя же не будет миллиона узлов в дереве. Да даже если и будет, для нынешнего компа десяток мегабайт - не смертельно.
Единственно, что может оказаться расточительно, - это хранение текстов, если они будут достаточно большие. В этом случае по мышиному клику можно будет считывать текстовое поле непосредственно из базы. Учитывая, что по ключевому полю будет создан индекс, выборка не должна занять много времени.
Записан
Dimyan
Гость
« Ответ #33 : 14-04-2004 12:10 » 

Alf, а по текстовому полю у меня тоже два вопроса
1) стоит ли (я просто в Access свою базу посмотрел) задавать полю ответ тип MEMO (ведь простое текстовое поле поддерживает только 255 символов, а это мало)?
2) Если считывать его из базы, то я так понимаю для этого надо применять могучую команду SELECT?
Записан
Alf
Гость
« Ответ #34 : 14-04-2004 14:33 » 

Цитата: Dimyan
Alf, а по текстовому полю у меня тоже два вопроса
1) стоит ли (я просто в Access свою базу посмотрел) задавать полю ответ тип MEMO (ведь простое текстовое поле поддерживает только 255 символов, а это мало)?
Если 255 - мало (а это действительно маловато, 3 строчки приблизительно), то MEMO, иначе подробные ответы не втиснутся.
Цитата: Dimyan
2) Если считывать его из базы, то я так понимаю для этого надо применять могучую команду SELECT?
Конечно, а как иначе ты получишь доступ к данным?
Нужно использовать конструкцию вроде
Код:
SELECT AnswerText
FROM FAQTable
WHERE (NodeID = ?)
и в качестве параметра передавать значение NodeID для текущего узла, если он является "файлом"
« Последнее редактирование: 25-11-2007 15:30 от Алексей1153++ » Записан
Dimyan
Гость
« Ответ #35 : 15-04-2004 03:36 » 

Alf, спасибо, теперь на пару дней зависну над изучением и перекладыванием кода.
Записан
Dimyan
Гость
« Ответ #36 : 17-04-2004 06:25 » 

Alf, с принципом работы я разобрался, но проникновениее в структуру дается тяжело, просто я незнаю все эти OleDb, сейчас учу но тяжко Жаль, из литиратуры только MSDN. Вчера весь вечер потратил на то чтоб дерево загружалось как и сохранялось (не элементом "Корневого каталога"), пока безрезультатно Жаль
Принцип рекурсии (дебагил с точкой останова, по твоему совету) довольно прояснился, полной ясности мешают опять же все эти OleDb.
Появилась следующая проблема, теперь прийдется менять весь алгоритм занесения данных в базу, обновления и сохранения.

----------------
Усиленно учу OleDb, тяжко Жаль, источник один и тот буржуйский
Мало времени Жаль
Только что оформил заказ в книжном интернет магазине на "Программирование на C#" Д. Либерти, говорят книга ценная, много хорошего материала по ADO.Net, но прийдет недели через две Жаль
Записан
Dimyan
Гость
« Ответ #37 : 21-04-2004 06:09 » 

Alf, у меня все получилось (правда пока на тестовом проекте)  Вот такой я вот
Завтра постараюсь выложить код (создавал на основе твего и еще двух примеров, один из которых из MSDN)
Только вопрос у меня: какой тип нужно присвоить DataColumn чтоб в него можно было нормально загружать данные поля с типом MEMO (из Access'овского файла БД)?
Записан
Alf
Гость
« Ответ #38 : 22-04-2004 06:46 » 

Dimyan, с типом DataColumn постараюсь определиться на выходные. А пока почитай новую статью о рекурсии, я ее сегодня ночью на сайт выложил. Потом расскажи, это ты хотел узнать или нет.
Записан
Alf
Гость
« Ответ #39 : 22-04-2004 07:04 » 

Цитата: Dimyan
Появилась следующая проблема, теперь прийдется менять весь алгоритм занесения данных в базу, обновления и сохранения.

Расскажи, что там проблематичного. Может, что смогу посоветовать.
Кстати, что там у тебя с сохранением? По-моему, там совершенно не должно быть никаких проблем, если ты будешь одновременно с созданием новых узлов дерева тут же заносить их в базу. Тогда сохранение и не понадобится вовсе, т.к. дерево на экране и в базе данных у тебя в каждый момент будет синхронизировано.
Останется только начальная загрузка из базы в дерево и добавление узлов. Да и добавление будет тривиально, ведь больше одного узла дерева за раз ты не можешь создать, а один узел добавить в базу очень легко.
Записан
Dimyan
Гость
« Ответ #40 : 24-04-2004 04:51 » 

Вот такой у меня код получился:
Загрузка:
Код:
private void FillTree()
{
dsFAQBuilder.Clear();
oleDbDataAdapter1.Fill(dsFAQBuilder);

if(treeContents.Nodes.Count > 0)
{
treeContents.Nodes.Clear();
}

for(int i =0; i<dsFAQBuilder.Tables[0].Rows.Count; i++)
{
if(Convert.ToInt32(dsFAQBuilder.Tables[0].Rows[i][1])==0)
{
TreeNode tn = new TreeNode();
tn.Text = dsFAQBuilder.Tables[0].Rows[i][2].ToString();
tn.Tag = dsFAQBuilder.Tables[0].Rows[i][0];
tn.ImageIndex = 0;
tn.SelectedImageIndex = 0;
treeContents.Nodes.Add(tn);
}
}

foreach(TreeNode nd in treeContents.Nodes)
{
nd.Nodes.AddRange(GetNodes(Convert.ToInt32(nd.Tag)));
}
}
//*********************************************************************************************//

private TreeNode[] GetNodes(int ID)
{
DataTable tbl = dsFAQBuilder.Tables[0];
ArrayList nds = new ArrayList();

for(int i=0; i< dsFAQBuilder.Tables[0].Rows.Count; i++)
{
if(Convert.ToInt32(dsFAQBuilder.Tables[0].Rows[i][1])==ID)
{

TreeNode tn = new TreeNode();
tn.Text = dsFAQBuilder.Tables[0].Rows[i][2].ToString();
tn.Tag = dsFAQBuilder.Tables[0].Rows[i][0];

if(Convert.ToInt32(dsFAQBuilder.Tables[0].Rows[i][3])==0)
{
tn.ImageIndex = 1;
tn.SelectedImageIndex = 1;
}
else
{
tn.ImageIndex = 0;
tn.SelectedImageIndex = 0;
}
tn.Nodes.AddRange(GetNodes(Convert.ToInt32(dsFAQBuilder.Tables[0].Rows[i][0])));
nds.Add(tn);
}
}

TreeNode[] ndarr = new TreeNode[nds.Count];
int ii = 0;
foreach(TreeNode tnd in nds)
{
ndarr[ii] = tnd;
ii++;
}
return ndarr;
}

Показ ответа:
Код:
private void treeContents_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
{
OleDbCommand cmdGetSql = new OleDbCommand(strSqlCmdAnswer, oleDbConnection1);
OleDbParameter prmNodeID = new OleDbParameter("NodeID", OleDbType.Integer, 4);
cmdGetSql.Parameters.Add(prmNodeID);
oleDbConnection1.Open();
cmdGetSql.Parameters["NodeID"].Value =(int) treeContents.SelectedNode.Tag;

try
{
FAQTextBox.Text = (String)cmdGetSql.ExecuteScalar();
}
catch
{
FAQTextBox.Text = "";
}
oleDbConnection1.Close();
}
А вот так вношу изменения в базу из DataSet
Код:
private void menuItem_Save_Click(object sender, System.EventArgs e)
{
oleDbDataAdapter1.Update(dsFAQBuilder);
}
Сохранение наверно переделаю как ты говоришь после каждого изменения.
« Последнее редактирование: 25-11-2007 15:32 от Алексей1153++ » Записан
Dimyan
Гость
« Ответ #41 : 24-04-2004 05:02 » 

Сейчас для загрузки в DatsSet я делаю вот такой запрос
SELECT NodeID, NodeName, NodeType, ParentID FROM FAQTable
т.е. не трачу время на заполнение поля AnswerText, т.к. его я при отображеннии достаю из базы.
 "SELECT AnswerText FROM FAQTable WHERE (NodeID = ?)"  - это запрс для добытия ответа
Сейчас пока с заполнением базы все нормально т.к. я использую DatsSet, а потом его записываю в mdb, но хотел спросить:
Имеет ли смысл (хотябы для экономии памяти) отказатся от использования DatsSet и работать на прямую с базой?
Если да то тут какраз и проблемы с заполнением Жаль я пока еще не разодрался как напрямую работать с файлом, например найти строку и отредактировать (переименование), удалить или добавить новую?
Записан
Dimyan
Гость
« Ответ #42 : 24-04-2004 05:03 » new

Сейчас я переименовываю итем вот так:
Код:
/// <summary>
/// Редактирование имен элементов TreeView
/// </summary>
private void treeContents_AfterLabelEdit(object sender, System.Windows.Forms.NodeLabelEditEventArgs e)
{
if (e.Label != null)
{
if(e.Label.Length > 0)
{
e.Node.EndEdit(false);
DataRow foundRow;
foundRow = dsFAQBuilder.Tables[0].Rows.Find((object)e.Node.Tag);
foundRow.BeginEdit();
foundRow[2] = e.Label;
foundRow.EndEdit();
}
else
{
e.CancelEdit = true;
MessageBox.Show("Неправильное имя.\nВведите не пустое значение",
"Редактирование имени");
e.Node.BeginEdit();
}
}
}
« Последнее редактирование: 25-11-2007 15:34 от Алексей1153++ » Записан
Dimyan
Гость
« Ответ #43 : 24-04-2004 05:06 » 

Ой чуть не забыл
Она в памяти гдето 17Мб занимает, почему такие дикие размеры?  Ха-ха-ха
Можно ли уменьшить это значение?
Записан
Страниц: 1 [2]  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines