动态自定义工具栏

Dynamic custom toolbar

由于 class cl_gui_alv_grid 中的 "toolbar" 事件,我尝试根据给定标准动态构建工具栏。

问题是工具栏正在获取我的自定义按钮,但一旦我的条件不再匹配并且我想删除一个按钮,工具栏就不会刷新。下面的示例

"Refresh button


CLEAR ls_toolbar.
  ls_toolbar-icon        = icon_refresh.
  ls_toolbar-quickinfo   = TEXT-ref.
  ls_toolbar-butn_type   = 0.
  ls_toolbar-text        = TEXT-ref.
  ls_toolbar-function    = 'REFRESH'.
  ls_toolbar-disabled    = abap_false.
  APPEND ls_toolbar      TO e_object->mt_toolbar.

  "Save button
  IF my_criteria is false.
    DELETE e_object->mt_toolbar WHERE function EQ 'SAVE'.
  ELSE.
    CLEAR ls_toolbar.
    ls_toolbar-icon        = icon_system_save.
    ls_toolbar-quickinfo   = TEXT-sav.
    ls_toolbar-butn_type   = 0.
    ls_toolbar-text        = TEXT-sav.
    ls_toolbar-function    = 'LAMA_SAVE'.
    ls_toolbar-disabled    = abap_false.
    APPEND ls_toolbar      TO e_object->mt_toolbar.

  ENDIF.

当我创建我的 ALV 时,我会调用方法 lo_alv->set_toolbar_interactive( ).

当我进入调试模式时,我看到添加或删除了保存按钮,但一旦工具栏至少显示一次,它就不会反映在屏幕上。

如果我没记错的话,refreshing the ALV grid does not rebuild the toolbar

我认为您必须使用 'SET_TABLE_FOR_FIRST_DISPLAY' 重新初始化 ALV 网格才能获得额外的工具栏功能。

我可以实现您正在寻找的功能,但不清楚您的确切流程是什么,问题可能有多个来源。所以,这里有一个简短的演示你应该如何做(程序在工具栏中显示一个按钮,你点击它然后它消失,其余的 ALV 保持不变)。

REPORT zdemo.
CLASS lcl_app DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS pbo.
    CLASS-METHODS on_user_command FOR EVENT user_command OF cl_gui_alv_grid
            IMPORTING sender e_ucomm.
    CLASS-METHODS handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
            IMPORTING e_object e_interactive.
    CLASS-DATA alv_grid TYPE REF TO cl_gui_alv_grid.
    CLASS-DATA flights TYPE TABLE OF sflight.
ENDCLASS.

CLASS lcl_app IMPLEMENTATION.
  METHOD pbo.
    DATA: it_layout  TYPE lvc_s_layo,
          it_fcat    TYPE lvc_t_fcat,
          ls_exclude TYPE ui_func,
          gs_variant TYPE disvariant,
          lt_exclude TYPE ui_functions.

    IF alv_grid IS NOT BOUND.
      SELECT * FROM sflight INTO TABLE flights.

      ls_exclude = cl_gui_alv_grid=>mc_fc_excl_all.
      APPEND ls_exclude TO lt_exclude.

      CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
        EXPORTING i_structure_name = 'SFLIGHT'
        CHANGING ct_fieldcat = it_fcat
        EXCEPTIONS OTHERS = 3.
      CHECK sy-subrc = 0.

      CREATE OBJECT alv_grid
        EXPORTING
          i_parent = cl_gui_container=>screen0.

      SET HANDLER handle_toolbar FOR alv_grid.
      SET HANDLER on_user_command FOR alv_grid.
      CALL METHOD alv_grid->set_table_for_first_display
        EXPORTING
          is_layout            = it_layout
          it_toolbar_excluding = lt_exclude
          is_variant           = gs_variant
        CHANGING
          it_outtab            = flights
          it_fieldcatalog      = it_fcat
        EXCEPTIONS
          OTHERS               = 4.
    ENDIF.
  ENDMETHOD.

  METHOD handle_toolbar.
    DATA ls_toolbar TYPE stb_button.
    IF e_interactive = abap_false.
      " Added the first time only
      ls_toolbar-function  = 'DEMO'.
      ls_toolbar-text      = 'Click me and I will disappear'.
      APPEND ls_toolbar TO e_object->mt_toolbar.
    ENDIF.
  ENDMETHOD.

  METHOD on_user_command.
    IF e_ucomm = 'DEMO'.
      sender->set_toolbar_interactive( ).
    ENDIF.
  ENDMETHOD.
ENDCLASS.

PARAMETERS dummy.

AT SELECTION-SCREEN OUTPUT.
  lcl_app=>pbo( ).

桑德拉·罗西是对的。 有两个不同的 ALVG 实例,它与处理程序混淆,这就是工具栏未正确刷新的原因。

谢谢大家,

如果我创建一个 ALV 网格实例 (1),将它添加到父自定义容器,设置它的处理程序,使用 instance1->free() and free instance1 释放它,然后...添加一个新的相同的 ALV 网格实例 ( 2) 对于同一个自定义容器,带有处理程序,(2) 的处理程序不工作((1) 的处理程序也不工作!),并且一直显示 (1) 的工具栏。

摆脱这种不受欢迎的状态,并获得动态工具栏...

如果我在 (1) 的创建和释放与 (2) 的创建之间放置一个简单的 cl_gui_cfw=>flush( ),(2) 的处理程序将按预期工作,并且工具栏会反映图标实例 (2),正如预期的那样。

如前所述,这仅适用于创建了两个实例的情况 "in one go"。只有一个就不会出现这个问题。