5.Drag & Drop
不同Control之间可以实现drag,drop事件,实现拖动操作。
示例1:drag & drop between alv and tree
"容器对象
DATA:lo_container1 TYPE REF TO cl_gui_docking_container.
DATA:lo_container2 TYPE REF TO cl_gui_docking_container.
"tree对象
DATA:lo_tree TYPE REF TO cl_gui_simple_tree.
"alv对象
DATA:lo_alv TYPE REF TO cl_gui_alv_grid.
"layout
DATA:lv_layout type lvc_s_layo.
"drag & drop操作
DATA:lo_drag_alv TYPE REF TO cl_dragdrop.
DATA:lo_drag_tree TYPE REF TO cl_dragdrop.
"设置字段,清空字段动作
DATA:lo_alv_set TYPE REF TO cl_dragdrop.
DATA:lo_alv_clear TYPE REF TO cl_dragdrop.
"alv表
DATA:lt_out TYPE TABLE OF spfli.
DATA:ls_out LIKE LINE OF lt_out.
"tree表
DATA:lt_tree TYPE TABLE OF mtreesnode WITH DEFAULT KEY.
DATA:ls_tree LIKE LINE OF lt_tree.
"dragdrop传输数据结构
CLASS c_dragdropobj DEFINITION.
PUBLIC SECTION.
DATA:ls_spfli TYPE spfli.
DATA:index TYPE I.
DATA:lv_func TYPE C LENGTH 10.
ENDCLASS.
"dragdrop event
CLASS c_event_handler DEFINITION.
"事件触发顺序:alv drag->tree drop->alv drop complete
"事件触发顺序:tree drag->alv drop->tree drop complete
PUBLIC SECTION.
CLASS-DATA:lv_drag_flag TYPE I.
CLASS-METHODS:m_alv_ondrag FOR EVENT ondrag OF cl_gui_alv_grid
IMPORTING e_row e_column es_row_no e_dragdropobj.
CLASS-METHODS:m_alv_ondrop FOR EVENT ondrop OF cl_gui_alv_grid
IMPORTING e_row e_column es_row_no e_dragdropobj.
CLASS-METHODS:m_alv_ondrop_comp FOR EVENT ondropcomplete OF cl_gui_alv_grid
IMPORTING e_row e_column e_dragdropobj.
CLASS-METHODS:m_tree_ondrag FOR EVENT on_drag OF cl_gui_simple_tree
IMPORTING node_key drag_drop_object.
CLASS-METHODS:m_tree_ondrop FOR EVENT on_drop OF cl_gui_simple_tree
IMPORTING node_key drag_drop_object.
CLASS-METHODS:m_tree_ondrop_comp FOR EVENT on_drop_complete OF cl_gui_simple_tree
IMPORTING node_key drag_drop_object.
ENDCLASS.
CLASS c_event_handler IMPLEMENTATION.
"alv drag
METHOD m_alv_ondrag.
DATA:lo_data TYPE REF TO c_dragdropobj.
"创建数据结构对象
CREATE OBJECT lo_data.
READ TABLE lt_out INTO ls_out INDEX e_row-index.
lo_data->index = e_row-index.
lo_data->ls_spfli = ls_out.
"设置传输数据
e_dragdropobj->object = lo_data.
ENDMETHOD.
"alv drop
METHOD m_alv_ondrop.
DATA:lo_data TYPE REF TO c_dragdropobj.
CATCH SYSTEM-EXCEPTIONS move_cast_error = 1.
lo_data ?= e_dragdropobj->object.
IF lo_data->lv_func = 'COPY'.
READ TABLE lt_out INTO ls_out INDEX e_row-index.
"插入copy行
INSERT ls_out INTO lt_out INDEX e_row-index.
ELSEIF lo_data->lv_func = 'DEL'.
DELETE lt_out INDEX e_row-index.
ENDIF.
ENDCATCH.
IF sy-subrc <> 0.
e_dragDropObj->abort( ).
ENDIF.
ENDMETHOD.
"alv drop complete
METHOD m_alv_ondrop_comp.
DATA:lo_data TYPE REF TO c_dragdropobj.
DATA:ls_stable type lvc_s_stbl.
IF lv_drag_flag = 1.
EXIT.
ENDIF.
CATCH SYSTEM-EXCEPTIONS move_cast_error = 1.
lo_data ?= e_dragdropobj->object.
IF e_dragdropobj->effect = cl_dragdrop=>move.
"删除内表drag行
DELETE lt_out INDEX lo_data->index.
IF sy-subrc = 0.
ls_stable-row = 'X'.
ls_stable-col = 'X'.
lo_alv->refresh_table_display(
EXPORTING
is_stable = ls_stable
).
ENDIF.
ENDIF.
ENDCATCH.
IF sy-subrc <> 0.
e_dragDropObj->abort( ).
ENDIF.
ENDMETHOD.
"tree drag
METHOD m_tree_ondrag.
DATA:lo_data TYPE REF TO c_dragdropobj.
"创建数据结构对象
CREATE OBJECT lo_data.
"设置拖动节点信息
lo_data->lv_func = node_key.
drag_drop_object->object = lo_data.
ENDMETHOD.
"tree drop
METHOD m_tree_ondrop.
"新节点
DATA:lt_new_tree TYPE TABLE OF mtreesnode.
DATA:ls_new_node TYPE mtreesnode.
DATA:lo_data TYPE REF TO c_dragdropobj.
CATCH SYSTEM-EXCEPTIONS move_cast_error = 1.
"获取传输数据
lo_data ?= drag_drop_object->object.
ls_new_node-node_key = lo_data->ls_spfli-carrid.
ls_new_node-relatkey = node_key.
ls_new_node-relatship = cl_gui_simple_tree=>relat_last_child.
ls_new_node-text = lo_data->ls_spfli-carrid.
READ TABLE lt_tree WITH KEY node_key = ls_new_node-node_key INTO ls_tree.
IF sy-subrc <> 0.
APPEND ls_new_node TO lt_tree.
APPEND ls_new_node TO lt_new_tree.
lo_tree->add_nodes(
table_structure_name = 'MTREESNODE'
node_table = lt_new_tree
).
lv_drag_flag = 0.
ELSE.
MESSAGE 'repeat id' TYPE 'I'.
lv_drag_flag = 1.
ENDIF.
ENDCATCH.
IF sy-subrc <> 0.
"some failed,abort
drag_drop_object->abort( ).
ENDIF.
ENDMETHOD.
"tree drop complete
METHOD m_tree_ondrop_comp.
DATA:ls_stable type lvc_s_stbl.
MESSAGE 'suceess' TYPE 'I'.
ls_stable-row = 'X'.
ls_stable-col = 'X'.
"刷新
lo_alv->refresh_table_display(
EXPORTING
is_stable = ls_stable
).
ENDMETHOD.
ENDCLASS.
CLASS c_main DEFINITION.
PUBLIC SECTION.
METHODS:constructor.
METHODS:m_init.
METHODS:m_free.
ENDCLASS.
CLASS c_main IMPLEMENTATION.
METHOD constructor.
CREATE OBJECT lo_container1
EXPORTING
repid = sy-repid
dynnr = '100'
extension = 200
side = cl_gui_docking_container=>dock_at_left.
CREATE OBJECT lo_container2
EXPORTING
repid = sy-repid
dynnr = '100'
extension = 1000
side = cl_gui_docking_container=>dock_at_left.
"初始化tree
CREATE OBJECT lo_tree
EXPORTING
parent = lo_container1
node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single.
"初始化alv
CREATE OBJECT lo_alv
EXPORTING
i_parent = lo_container2.
ENDMETHOD.
METHOD m_init.
DATA:lv_handle_tree TYPE I.
DATA:lv_handle_alv TYPE I.
DATA:lv_set TYPE I.
DATA:lv_clear TYPE I.
DATA:lv_opt TYPE I.
"drag&drop控制字段
DATA:lt_drdr TYPE lvc_t_drdr.
DATA:ls_drdr TYPE lvc_s_drdr.
"初始化数据
SELECT * FROM spfli INTO CORRESPONDING FIELDS OF TABLE lt_out.
"设置alv的drap,drop行为,直接拖动move,按住ctrl拖动copy
CREATE OBJECT lo_drag_alv.
lv_opt = cl_dragdrop=>copy + cl_dragdrop=>move.
lo_drag_alv->add(
EXPORTING
flavor = 'Line'
dragsrc = 'X'
droptarget = 'X'
effect = lv_opt
).
lo_drag_alv->get_handle( IMPORTING handle = lv_handle_alv ).
"CNTR_DDID,指定control;
"GRID_DDID,指定grid;
"指定列,COL_DDID;
"指定行,ROW_DDID;
"指定字段,FIELDNAME;
"alv layout设置行drag
lv_layout-s_dragdrop-row_ddid = lv_handle_alv.
CREATE OBJECT lo_drag_tree.
lv_opt = cl_dragdrop=>copy + cl_dragdrop=>move.
lo_drag_tree->add(
EXPORTING
flavor = 'Line'
dragsrc = 'X'
droptarget = 'X'
effect = lv_opt
).
lo_drag_tree->get_handle( IMPORTING handle = lv_handle_tree ).
"初始node节点
CLEAR ls_tree.
ls_tree-node_key = 'TREE'.
ls_tree-isfolder = 'X'.
ls_tree-text = 'Tree Root'.
APPEND ls_tree TO lt_tree.
CLEAR ls_tree.
ls_tree-node_key = 'NODE1'.
ls_tree-isfolder = 'X'.
ls_tree-text = 'Node 1'.
ls_tree-relatkey = 'TREE'.
ls_tree-relatship = cl_gui_simple_tree=>relat_last_child.
ls_tree-dragdropid = lv_handle_tree.
APPEND ls_tree TO lt_tree.
"动作节点,不指定dragdropid,alv不能拖动到此节点
lo_drag_tree->get_handle( IMPORTING handle = lv_handle_tree ).
CLEAR ls_tree.
ls_tree-node_key = 'NODE2'.
ls_tree-isfolder = 'X'.
ls_tree-text = 'Node Action'.
ls_tree-relatkey = 'TREE'.
ls_tree-relatship = cl_gui_simple_tree=>relat_last_child.
APPEND ls_tree TO lt_tree.
"copy动作
CLEAR ls_tree.
ls_tree-node_key = 'COPY'.
ls_tree-isfolder = ''.
ls_tree-text = 'copy'.
ls_tree-relatkey = 'NODE2'.
ls_tree-relatship = cl_gui_simple_tree=>relat_last_child.
ls_tree-dragdropid = lv_handle_tree.
APPEND ls_tree TO lt_tree.
"delete动作
CLEAR ls_tree.
ls_tree-node_key = 'DEL'.
ls_tree-isfolder = ''.
ls_tree-text = 'delete'.
ls_tree-relatkey = 'NODE2'.
ls_tree-relatship = cl_gui_simple_tree=>relat_last_child.
ls_tree-dragdropid = lv_handle_tree.
APPEND ls_tree TO lt_tree.
"显示tree
lo_tree->add_nodes(
EXPORTING
table_structure_name = 'MTREESNODE'
node_table = lt_tree ).
lo_tree->expand_node( node_key = 'TREE' ).
"显示alv
lo_alv->set_table_for_first_display(
EXPORTING
i_structure_name = 'SPFLI'
is_layout = lv_layout
CHANGING
it_outtab = lt_out
).
"设置事件
SET HANDLER c_event_handler=>m_alv_ondrag FOR lo_alv.
SET HANDLER c_event_handler=>m_alv_ondrop FOR lo_alv.
SET HANDLER c_event_handler=>m_alv_ondrop_comp FOR lo_alv.
SET HANDLER c_event_handler=>m_tree_ondrag FOR lo_tree.
SET HANDLER c_event_handler=>m_tree_ondrop FOR lo_tree.
SET HANDLER c_event_handler=>m_tree_ondrop_comp FOR lo_tree.
ENDMETHOD.
METHOD m_free.
IF lo_container1 IS NOT INITIAL.
lo_container1->free( ).
ENDIF.
IF lo_container2 IS NOT INITIAL.
lo_container2->free( ).
ENDIF.
CLEAR lo_container1.
CLEAR lo_container2.
CLEAR lo_tree.
CLEAR lo_alv.
LEAVE PROGRAM.
ENDMETHOD.
ENDCLASS.
DATA:lo_main TYPE REF TO c_main.
START-OF-SELECTION.
PERFORM f_drag_drop.
FORM f_drag_drop.
CREATE OBJECT lo_main.
lo_main->m_init( ).
CALL SCREEN 100.
ENDFORM.
示例2:drag tree function code to alv
"容器对象
DATA:lo_container1 TYPE REF TO cl_gui_docking_container.
DATA:lo_container2 TYPE REF TO cl_gui_docking_container.
"tree对象
DATA:lo_tree TYPE REF TO cl_gui_simple_tree.
"alv对象
DATA:lo_alv TYPE REF TO cl_gui_alv_grid.
"layout
DATA:lv_layout type lvc_s_layo.
"drag & drop操作
"设置字段,清空字段动作
DATA:lo_alv_set TYPE REF TO cl_dragdrop.
DATA:lo_alv_clear TYPE REF TO cl_dragdrop.
DATA:lo_tree_set TYPE REF TO cl_dragdrop.
DATA:lo_tree_clear TYPE REF TO cl_dragdrop.
"alv表
TYPES:BEGIN OF s_out.
INCLUDE TYPE spfli.
"控制单元格dragdrop
TYPES:t_drdr TYPE lvc_t_drdr.
TYPES:END OF s_out.
DATA:lt_out TYPE TABLE OF s_out.
DATA:ls_out LIKE LINE OF lt_out.
"tree表
DATA:lt_tree TYPE TABLE OF mtreesnode WITH DEFAULT KEY.
DATA:ls_tree LIKE LINE OF lt_tree.
"dragdrop传输数据结构
CLASS c_dragdropobj DEFINITION.
PUBLIC SECTION.
DATA:ls_spfli TYPE s_out.
DATA:index TYPE I.
DATA:lv_func TYPE C LENGTH 10.
ENDCLASS.
"dragdrop event
CLASS c_event_handler DEFINITION.
"事件触发顺序:tree drag->alv drop->tree drop complete
PUBLIC SECTION.
CLASS-METHODS:m_alv_ondrop FOR EVENT ondrop OF cl_gui_alv_grid
IMPORTING e_row e_column es_row_no e_dragdropobj.
CLASS-METHODS:m_tree_ondrag FOR EVENT on_drag OF cl_gui_simple_tree
IMPORTING node_key drag_drop_object.
CLASS-METHODS:m_tree_ondrop_comp FOR EVENT on_drop_complete OF cl_gui_simple_tree
IMPORTING node_key drag_drop_object.
ENDCLASS.
CLASS c_event_handler IMPLEMENTATION.
"alv drop
METHOD m_alv_ondrop.
DATA:lo_data TYPE REF TO c_dragdropobj.
"drag&drop控制字段
DATA:lt_drdr TYPE lvc_t_drdr.
DATA:ls_drdr TYPE lvc_s_drdr.
DATA:lv_set TYPE I.
DATA:lv_clear TYPE I.
CATCH SYSTEM-EXCEPTIONS move_cast_error = 1.
lo_data ?= e_dragdropobj->object.
IF lo_data->lv_func = 'SET'.
READ TABLE lt_out INTO ls_out INDEX e_row-index.
ls_out-fltype = 'X'.
CLEAR ls_drdr.
lo_alv_clear->get_handle( IMPORTING handle = lv_clear ).
ls_drdr-fieldname = 'FLTYPE'.
ls_drdr-dragdropid = lv_clear.
APPEND ls_drdr TO lt_drdr.
ls_out-t_drdr = lt_drdr.
MODIFY lt_out FROM ls_out INDEX e_row-index TRANSPORTING fltype t_drdr.
ELSEIF lo_data->lv_func = 'CLEAR'.
READ TABLE lt_out INTO ls_out INDEX e_row-index.
ls_out-fltype = ''.
CLEAR ls_drdr.
lo_alv_set->get_handle( IMPORTING handle = lv_set ).
ls_drdr-fieldname = 'FLTYPE'.
ls_drdr-dragdropid = lv_set.
APPEND ls_drdr TO lt_drdr.
ls_out-t_drdr = lt_drdr.
MODIFY lt_out FROM ls_out INDEX e_row-index TRANSPORTING fltype t_drdr.
ENDIF.
ENDCATCH.
IF sy-subrc <> 0.
e_dragDropObj->abort( ).
ENDIF.
ENDMETHOD.
"tree drag
METHOD m_tree_ondrag.
DATA:lo_data TYPE REF TO c_dragdropobj.
"创建数据结构对象
CREATE OBJECT lo_data.
"设置拖动节点信息
lo_data->lv_func = node_key.
drag_drop_object->object = lo_data.
ENDMETHOD.
"tree drop complete
METHOD m_tree_ondrop_comp.
DATA:ls_stable type lvc_s_stbl.
MESSAGE 'suceess' TYPE 'I'.
ls_stable-row = 'X'.
ls_stable-col = 'X'.
"刷新
lo_alv->refresh_table_display(
EXPORTING
is_stable = ls_stable
).
ENDMETHOD.
ENDCLASS.
CLASS c_main DEFINITION.
PUBLIC SECTION.
METHODS:constructor.
METHODS:m_init.
METHODS:m_free.
ENDCLASS.
CLASS c_main IMPLEMENTATION.
METHOD constructor.
CREATE OBJECT lo_container1
EXPORTING
repid = sy-repid
dynnr = '100'
extension = 200
side = cl_gui_docking_container=>dock_at_left.
CREATE OBJECT lo_container2
EXPORTING
repid = sy-repid
dynnr = '100'
extension = 1000
side = cl_gui_docking_container=>dock_at_left.
"初始化tree
CREATE OBJECT lo_tree
EXPORTING
parent = lo_container1
node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single.
"初始化alv
CREATE OBJECT lo_alv
EXPORTING
i_parent = lo_container2.
ENDMETHOD.
METHOD m_init.
DATA:lv_tree_set TYPE I.
DATA:lv_tree_clear TYPE I.
DATA:lv_alv_set TYPE I.
DATA:lv_alv_clear TYPE I.
DATA:lv_opt TYPE I.
"drag&drop控制字段
DATA:lt_drdr TYPE lvc_t_drdr.
DATA:ls_drdr TYPE lvc_s_drdr.
"初始化数据
SELECT * FROM spfli INTO CORRESPONDING FIELDS OF TABLE lt_out.
"CNTR_DDID,指定control;
"GRID_DDID,指定grid;
"指定列,COL_DDID;
"指定行,ROW_DDID;
"指定字段,FIELDNAME;
"alv layout设置指定dragdrop字段
lv_layout-s_dragdrop-fieldname = 'T_DRDR'.
"初始node节点
CLEAR ls_tree.
ls_tree-node_key = 'TREE'.
ls_tree-isfolder = 'X'.
ls_tree-text = 'Tree Root'.
APPEND ls_tree TO lt_tree.
CLEAR ls_tree.
ls_tree-node_key = 'NODE1'.
ls_tree-isfolder = 'X'.
ls_tree-text = 'Node 1'.
ls_tree-relatkey = 'TREE'.
ls_tree-relatship = cl_gui_simple_tree=>relat_last_child.
APPEND ls_tree TO lt_tree.
"设置tree drag,drop动作
CREATE OBJECT lo_tree_set.
lv_opt = cl_dragdrop=>move.
lo_tree_set->add(
EXPORTING
flavor = 'Line'
dragsrc = 'X'
droptarget = ''
effect = lv_opt
).
lo_tree_set->get_handle( IMPORTING handle = lv_tree_set ).
CREATE OBJECT lo_tree_clear.
lv_opt = cl_dragdrop=>move.
lo_tree_clear->add(
EXPORTING
flavor = 'Line'
dragsrc = 'X'
droptarget = ''
effect = lv_opt
).
lo_tree_clear->get_handle( IMPORTING handle = lv_tree_clear ).
"设置tree节点for 单元格drag drop
CLEAR ls_tree.
ls_tree-node_key = 'SET'.
ls_tree-isfolder = ''.
ls_tree-text = 'set flag'.
ls_tree-relatkey = 'NODE1'.
ls_tree-relatship = cl_gui_simple_tree=>relat_last_child.
ls_tree-dragdropid = lv_tree_set.
APPEND ls_tree TO lt_tree.
CLEAR ls_tree.
ls_tree-node_key = 'CLEAR'.
ls_tree-isfolder = ''.
ls_tree-text = 'clear flag'.
ls_tree-relatkey = 'NODE1'.
ls_tree-relatship = cl_gui_simple_tree=>relat_last_child.
ls_tree-dragdropid = lv_tree_clear.
APPEND ls_tree TO lt_tree.
"设置alv drag drop动作
"设置alv单元格drag,drop
"设置单元格动作
CREATE OBJECT lo_alv_set.
lv_opt = cl_dragdrop=>move.
lo_alv_set->add(
EXPORTING
flavor = 'Line'
dragsrc = ''
droptarget = 'X'
effect = lv_opt
).
lo_alv_set->get_handle( IMPORTING handle = lv_alv_set ).
CREATE OBJECT lo_alv_clear.
lv_opt = cl_dragdrop=>move.
lo_alv_clear->add(
EXPORTING
flavor = 'Line'
dragsrc = ''
droptarget = 'X'
effect = lv_opt
).
lo_alv_clear->get_handle( IMPORTING handle = lv_alv_clear ).
LOOP AT lt_out INTO ls_out.
"标志为x,接收clear动作
IF ls_out-fltype = 'X'.
CLEAR ls_drdr.
ls_drdr-fieldname = 'FLTYPE'.
ls_drdr-dragdropid = lv_alv_clear.
APPEND ls_drdr TO lt_drdr.
ELSE.
CLEAR ls_drdr.
ls_drdr-fieldname = 'FLTYPE'.
ls_drdr-dragdropid = lv_alv_set.
APPEND ls_drdr TO lt_drdr.
ENDIF.
ls_out-t_drdr = lt_drdr.
MODIFY lt_out FROM ls_out.
ENDLOOP.
"显示tree
lo_tree->add_nodes(
EXPORTING
table_structure_name = 'MTREESNODE'
node_table = lt_tree ).
lo_tree->expand_node( node_key = 'TREE' ).
"显示alv
lo_alv->set_table_for_first_display(
EXPORTING
i_structure_name = 'SPFLI'
is_layout = lv_layout
CHANGING
it_outtab = lt_out
).
"设置事件
SET HANDLER c_event_handler=>m_alv_ondrop FOR lo_alv.
SET HANDLER c_event_handler=>m_tree_ondrag FOR lo_tree.
SET HANDLER c_event_handler=>m_tree_ondrop_comp FOR lo_tree.
ENDMETHOD.
METHOD m_free.
IF lo_container1 IS NOT INITIAL.
lo_container1->free( ).
ENDIF.
IF lo_container2 IS NOT INITIAL.
lo_container2->free( ).
ENDIF.
CLEAR lo_container1.
CLEAR lo_container2.
CLEAR lo_tree.
CLEAR lo_alv.
LEAVE PROGRAM.
ENDMETHOD.
ENDCLASS.
DATA:lo_main TYPE REF TO c_main.
START-OF-SELECTION.
PERFORM f_drag_drop.
FORM f_drag_drop.
CREATE OBJECT lo_main.
lo_main->m_init( ).
CALL SCREEN 100.
ENDFORM.