Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > СУБД, общие вопросы > Как создать дерево каталогов


Автор: Cashey 15.2.2006, 00:51
Довольно часто возникает необходимость создать так называемое "дерево каталогов", т.е. отображение условных каталогов как в проводнике Windows. Разумеется речь не идет только о каталогах файловой системы. Под термином "каталог" здесь подразумевается любое условное объединение данных. На пример, различные группы записей таблицы, относящиеся к разным разделам\подразделам.
В этой статье я объясню создание простого варианта такого "дерева каталогов".
И так, для создания отображения по средствам Visual FoxPro, необходимо:
1. Создать таблицу, содержащую поля, QUID, ParentQUID, Text, Lavel, в которых будут хранится соответсвенно - уникальный идентификатор текущей записи, уникальный идентификатор родительского каталога, текстовое название каталога или подкаталога и номер уровня вложенности.
2. Создать форму (или класс), на которую разместить с панели Form Controls, элемент ActiveX Control (OLEControl). В открывшемся окне Insert Object, выбрать элемент Microsoft TreeView Control, version 6 (или 5(SP2))
3. Создать на форме (или классе) следующие методы и свойства: openDBF(), NewKey(), addCatalog(), delCatalog(), addRecord(), getSelQUID(), getlevel(), showtree() и cnextkey. А также какой-нибудь метод, запускающий процесс заполнения дерева и добавления новых каталогов. В настоящем примере, я помещю код заполнения дерева в метод Init() формы, а добавление нового каталога, в специально созданный метод формы addCatalog().
4. Переименовать, для удобства, компонент Olecontrol1 в oleTree.
5. Заполнить свойство cnextkey значение "1_"
6. Заполнить соответсвующие методы кодом, аналогичным рассмотренному в этом примере

Метод oleTree.Init()
Код

LOCAL lcOldAlias, laFields, cKey, cParent

lcOldAlias = ALIAS()
lcDBFName = GETFILE('dbf')
IF EMPTY(m.lcDBFName)
    RETURN
ENDIF
IF THISFORM.OpenDBF(lcDBFName)
*!*  Здесь можно вызвать метод проверки корректности открытой таблицы.
    
    * Заполняем TreeView control значениями из таблицы.
    *----------------------------------------------------
    oNode = this.Nodes
    oNode.Clear

    SCAN
  cKey    = ALLTRIM(Quid)
  cParent = ALLTRIM(parentquid)
  IF ALLTRIM(parentQuid) = '0_'
    oNode.add(,1,ALLTRIM(Quid),ALLTRIM(text),0)
  ELSE
    oNode.add(ALLTRIM(parentQuid),4,ALLTRIM(Quid), ALLTRIM(text),0)
  ENDIF
  THISFORM.cNextKey = ALLTRIM(STR(VAL(Quid) + 1) + "_")
    ENDSCAN
ENDIF


Метод Form.OpenDBF()
Код

LPARAMETERS lcDBFName, llExclusive
SET MULTILOCKS ON

lcAlias = SUBSTR(lcDBFName, RAT("\",lcDBFName) + 1)
lcAlias = SUBSTR(lcAlias, 1, AT(".", lcAlias) - 1)

IF llExclusive
    USE (lcDBFName) IN 0 EXCLUSIVE
ENDIF

IF !USED(lcALIAS)
    USE (lcDBFName) IN 0 SHARED
ENDIF

If CursorGetProp("Buffering", lcALIAS) # 5
    CursorSetProp("Buffering", 5, lcALIAS)
ENDIF
thisform.alias = lcALIAS


Метод Form.AddCatalog()
Код

oNode = THISFORM.oleTree
Local oNewNode, cNewQUID, cNewName, cParentQUID, nLevel

cNewQUID    = ""
cNewName  = "Новый раздел"
cParentQUID = This.GetSelQUID()
nLevel    = This.GetLevel(oNode.SelectedItem) + 1

* Добавляем новую запись в таблицу
If This.AddRecord(@cNewQUID, @cNewName, cParentQUID, nLevel)
    * Если cNewRN не заполнен, то юзер просто отказался от создания
    If !Empty(cNewQUID)
  * Добавляем узел в коллекцию
  oNewNode = oNode.Nodes.Add(oNode.SelectedItem.Key, 4, cNewQUID + '_', cNewName, 1, 2)

  * Выделим и откроем новый каталог
  oNewNode.Expanded = .T.
  oNewNode.Selected = .T.
    EndIf
ENDIF
this.showtree()


Метод Form.AddRecord()
Код

LParam cNewQUID, cText, cParentQUID, nLevel

Local cKeyField, lResult

lResult = .F.

If !FLock(this.alias)
    Return lResult
EndIf

INSERT INTO (this.alias) (QUID, ParentQUID, Level, Text);
    VALUES (this.newkey(), cParentQUID+"_", nLevel, cText)

    lResult = TableUpdate(1, .T., this.alias)


UnLock In (this.alias)

Return lResult


Метод Form.NewKey()
Код

cKey = THIS.cNextKey
THIS.cNextKey = ALLTRIM(STR(VAL(THIS.cNextKey) + 1) + "_")
RETURN cKey


Метод Form.GetLevel()
Код

LParam oNode

If IsNull(This.OleTree.Nodes)
    Return 0
EndIf

Return Occurs("\", oNode.FullPath)


Метод Form.getselquid()
Код

LParam oNode
Local cKey

If Param() = 0
    cKey = THIS.oleTree.SelectedItem.Key
Else
    cKey = oNode.Key
EndIf

Return Left(cKey, Len(cKey)-1)


Метод Form.showtree()
Код

    oNode = this.oleTree.Nodes
    oNode.Clear
    SELECT (this.alias)
    SCAN
  IF ALLTRIM(parentQuid) = '0_'
    oNode.add(,1,ALLTRIM(Quid),ALLTRIM(text),0)
  ELSE
    oNode.add(ALLTRIM(parentQuid),4,ALLTRIM(Quid), ALLTRIM(text),0)
  ENDIF
  THISFORM.cNextKey = ALLTRIM(STR(VAL(Quid) + 1) + "_")
    ENDSCAN

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)