Показать сообщение отдельно
Старый 30.03.2017, 10:54   #7  
byte is offline
byte
Участник
 
36 / 31 (2) +++
Регистрация: 21.08.2007
В таком случае предложу свое решение. Его плюс в том, что при наличии летающих контролов, форму не нужно перенастраивать, все делается автоматически при нажатии одной кнопки.
Опытным путем удалось установить, что летающие поля при перечислении всех контролов формы встречаются дважды. При этом "летают" только доступные для редактирования поля. Заявленная функция находит такие поля и скрывает их, добавляя вместо них эти же поля. Вообще опять же опытным путем установил, что лучше добавлять поля, чем переносить их из датагрупп. Насколько я понял, в переносе полей и кроется проблема, т.к. они начинают встречаться на форме и в новом, и в изначальном месте, id у контролов совпадает.
Дисплей-методы не летают ввиду того, что недоступны для редактирования, даже если встречаются дважды. А эдит-методы мной не тестировались.

Добавляем на форму SysSetupForm кнопку:

X++:
void clicked()
{
    ;

    super();

    sysSetupForm.upc_flyingControlsRecreate();
}
В класс SysSetupForm добавляем следующие методы:
Перечисление летающих контролов:
X++:
container upc_flyingControlNumSet()
{
    Set set         = new Set(Types::Integer),
        flyingSet   = new Set(Types::Integer);

    void printControls(Object o)
    {
        FormBuildControl    formBuildControl;
        Object              control;
        int                 i;
        ;

        for (i=1; i<=o.controlCount(); i++)
        {
            formBuildControl    = o.controlNum(i);
            control             = formBuildControl;

            if( set.in(formBuildControl.id())           &&
                !formBuildControl.userHide()            &&
                this.formControlIsDataBound(control)    &&
                control.dataSource()                    &&
                control.dataField() )
            {
                flyingSet.add(formBuildControl.id());
            }

            set.add(formBuildControl.id());

            if (formBuildControl.isContainer())
                printControls(formBuildControl);
        }
    }
    ;

    printControls(this.design());

    return flyingSet.pack();
}
Вывод в инфолог летающих контролов:
X++:
void upc_flyingControlsPrint()
{
    Set                 set;
    SetIterator         si;
    FormControl         formControl;
    ;

    set = Set::create(this.upc_flyingControlNumSet());
    si  = new SetIterator(set);
    while(si.more())
    {
        formControl = editFormRun.control(si.value());
        info(strfmt('%1 %2', formControl.id(), formControl.name()) );

        si.next();
    }
}
Пересоздание контролов (скрытие сущетсвующего и добавление нового):
X++:
void upc_flyingControlsRecreate()
{
    Set                 set;
    SetIterator         si;
    FormTreeItem        formTreeItem;
    Object              control;
    int                 cnt;
    ;

    set = Set::create(this.upc_flyingControlNumSet());
    si  = new SetIterator(set);
    while(si.more())
    {
        control         = this.formControl(si.value());
        formTreeItem    = formControlTree.getItem(this.formControlTreeControl2Idx(si.value()));

        this.upc_formControlTreeUserAdd(
            control,
            formControlTree.getParent(formTreeItem.idx()),
            formTreeItem.idx() );

        control.userHide(true);
        cnt++;

        si.next();
    }

    info(strfmt('Обработано полей: %1.', cnt));
}
Добавление контрола на основе существующего:
X++:
public FormControl upc_formControlTreeUserAdd(
    Object      _control,
    TreeItemIdx _parentItemIdx,
    TreeItemIdx _insertAfterItemIdx = 0 )
{
    Object          newControl,
                    insertAfterControl;
    Object          parentControl;
    TreeNodeName    treeNodeName;
    int             i;
    ;

    if (formControlTree.getItem(_parentItemIdx))
    {
        parentControl = this.formControlTreeIdx2Control(_parentItemIdx);

        if (parentControl &&
            !parentControl.isContainer())
        {
            _insertAfterItemIdx = _parentItemIdx;
            _parentItemIdx      = formControlTree.getParent(_insertAfterItemIdx);
            parentControl       = this.formControlTreeIdx2Control(_parentItemIdx);
        }
    }

    if (!parentControl)
    {
        parentControl = this.design();
    }

    if (parentControl)
    {
        parentControl.useUserLayout(true);

        if (_insertAfterItemIdx)
        {
            insertAfterControl = this.formControlTreeIdx2Control(_insertAfterItemIdx);
        }

        if( this.formControlIsDataBound(_control)   &&
            _control.dataSource() )
        {
            if(_control.dataField())
            {
                newControl      = parentControl.addDataField(
                    _control.dataSource(),
                    _control.dataField(),
                    insertAfterControl);
            }
            else if(_control.dataMethod())
            {
                i               = 0;
                do
                {
                    i++;
                    treeNodeName    = strfmt('%1_%2_%3', curuserid(), i, _control.dataMethod());
                }
                while(this.formControlIsNameUsed(treeNodeName));

                newControl      = parentControl.addControl(
                    SysFormRun::controlType(classidget(_control)),
                    treeNodeName,
                    insertAfterControl);

                newControl.dataSource(_control.dataSource());
                newControl.dataMethod(_control.dataMethod());
                newControl.label(_control.label());
                newControl.helpText(_control.helpText());
            }
        }

        if (newControl)
        {
            newControl.markAsUserAdd(true);
            this.formControlTreeAddControl(
                newControl,
                _parentItemIdx,
                _insertAfterItemIdx,
                true);
        }
    }

    return newControl;
}
Ветка с датаметодом есть, но она не тестировалась мной.

Последний раз редактировалось byte; 30.03.2017 в 10:57.
За это сообщение автора поблагодарили: Logger (10), dech (5), Ace of Database (3).