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.