Показать сообщение отдельно
Старый 14.09.2010, 11:35   #27  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от db Посмотреть сообщение
Ну в общем тоже сделал.
X++:
private void autoSizeColumns(boolean _autoSizeColumns)
{
    void traverse(Object _parent)
    {
        // ...
    }
    traverse(this.design());
}
Такие велосипеды уже давно изобретены - см. Итератор с поддержкой методов обратного вызова для обработки контролов на форме
Цитата:
Сообщение от mazzy Посмотреть сообщение
Но я очень боюсь потери производительности при открытии форм при обработке контролов за счет обработки в SysSetupFormRun (особенно на маломощных компах. а такие есть).
Нет ее - этой потери производительности Если есть сомнения, можно код перебора контролов обрамить следующим образом и посмотреть, сколько времени потратится:
X++:
UtcDateTime     dateTimeStart;
;
dateTimeStart = DateTimeUtil::utcNow();
// лопатим контролы...
info( strfmt( @"%1 мс", DateTimeUtil::getDifference( DateTimeUtil::utcNow(), dateTimeStart ) * 10 ) );
Цитата:
Сообщение от mazzy Посмотреть сообщение
стопудово после нас программисты заказичка будут крыть нас матерными словами за такой подход... у них есть формы-монстры, которые они сами прогают... или не будут крыть?..
Не будут, если дать им возможность легко "встраивать" свои формы-монстры в механизм управления автоподбором ширины колонок в гриде.
Цитата:
Сообщение от mazzy Посмотреть сообщение
поэтому я предполагал, что буду изменять метод init и свойство autodeclaration во всех формах, которые потенциально могут быть медленными из-за большого количества записей. Так придется менять меньше форм, чем "все формы". но все равно очень много
Тю!..
Цитата:
Сообщение от mazzy Посмотреть сообщение
может быть, действительно стоит изменить sysSetupFormRun, если нет глобального параметра для ядра. причем самые монстроидальные формы перечислить явно в switch, чтобы аксапта не тратила время на перебор контролов при открытии.
Какой еще switch?.. В общем, есть такой способ решения этой задачи (во многом схожий с тем, что уже обсуждалось):
  • в SysSetupFormRun делаются обработчики, вызываемые до и после инициализации формы (вызова super() в init()) - это позволяет не замусоривать своим кодом перекрытый init() и легко переносить потом модификации;
  • в SysSetupFormRun заводится метод, который возвращает множество названий форм, где надо перебить указанное свойство гридов. Во множество прописываются наиболее "тяжелые" формы с фиговой тучей полей в гридах (тормозит ведь именно на количестве полей, а не числе записей, ну еще на display-методах), соотв. добавить туда новую форму можно одной строкой кода. Для оптимизации множество кэшируется в GlobalCache;
  • В обработчике, вызываемом в SysSetupFormRun после инициализации формы, дергается метод, перебивающий свойствов гридов, если текущая форма - одна из множества.
Таким образом, получается минимум легко переносимых и настраиваемых кастомизаций.
\Classes\SysSetupFormRun\DEV_getSetOfFormNames2TweakGrid
X++:
// возвращает множество названий форм, на Grid'ах которых нужно отключить austoSizeColumns
protected Set DEV_getSetOfFormNames2TweakGrid()
{
    Set ret = infolog.globalCache().get( classstr(SysSetupFormRun), funcname(), null );
    ;
    if (!(  ret
        &&  ret.typeId() == Types::String
       ))
    {
        ret = new Set( Types::String );
        // собственно здесь нужно перечислить названия форм, которые нужно автоматом "допиливать" при старте
        ret.add( formstr(OfficialsTable_RU) );
        ret.add( formstr(PurchTable) );
        ret.add( formstr(SalesTable) );

        // запоминаем множество в globalCache, чтоб не создавать каждый раз
        infolog.globalCache().set( classstr(SysSetupFormRun), funcname(), ret );
    }
    return ret;
}
\Classes\SysSetupFormRun\DEV_initDesignPost - тут используется итератор из этой темы
X++:
// дополнительное допиливание дизайна формы после инициализации
protected void DEV_initDesignPost()
{
//  UtcDateTime     dateTimeStart;
    identifiername  formName = this.name();
    ;
    if (this.DEV_getSetOfFormNames2TweakGrid().in( formName ))
    {
//      dateTimeStart = DateTimeUtil::utcNow();
        DEV_iterateThroughFormControls( this.design(), null, staticmethodstr(DEV_FormHelpers, setGridAutoSizeColumnsOff), DEV_FormHelpers::addGridCtrlId2Set() );
//      info( strfmt( @"%1 мс", DateTimeUtil::getDifference( DateTimeUtil::utcNow(), dateTimeStart ) * 10 ) );
    }
}
\Classes\SysSetupFormRun\DEV_initDesignPre
X++:
// дополнительное допиливание дизайна формы до инициализации
protected void DEV_initDesignPre()
{
    // ACHTUNG! Эта модификация к проблеме grid'ов никакого отношения не имеет!
    // опционально вертаем окна взад в рамки основного окна клиента (точнее, текущего workspace'а)
    if (    this.form().design().windowType()                       == FormWindowType::Standard
        &&  DEV_UserInfoParameters::find().DefaultFormWindowType    == DEV_DefaultFormWindowType::Workspace
       )
    {
        this.form().design().windowType( FormWindowType::Workspace );
    }
}
\Classes\SysSetupFormRun\init
X++:
public void init()
{
    // <GEEU>
    this.raiseEvent_W(methodstr(FormRunListener_W, beforeInit));
    // </GEEU>
    this.DEV_initDesignPre();                   // наши модификации
    super();
    SysSecurityFormSetup::loadSecurity(this);
    this.dimensionFieldCtrls();
    this.inventStorageDimFieldCtrls();

    if (this.isWorkflowEnabled())
    {
        workflowControls = SysWorkflowFormControls::construct(this);
        workflowControls.initControls();
    }
    this.DEV_initDesignPost();                  // наши модификации
    // <GEEU>
    this.raiseEvent_W(methodstr(FormRunListener_W, afterInit));
    // </GEEU>
}
За это сообщение автора поблагодарили: mazzy (2).