RCP e4 应用程序的@CanExecute 评估

Evaluation of @CanExecute for RCP e4 application

RCP E4 应用程序包含一个 TreeViewer,用于管理“包”集合的 visivility/selection。该部分被命名为 Package Navigator。

当一个包准备发送时,TreeViewer 图标显示 以及开始发货的按钮 应该启用。

当包未准备好时,图标为 并且发送按钮(处理程序)应该被禁用。

实现这样的代码 行为是:

private TreeViewer viewer;
    @PostConstruct
    public void createComposite(Composite parent, IEnviosService theModel) {
        ...         
        Tree t = (Tree) viewer.getControl();
        t.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                boolean check = false;
                System.out.print("Selection listener ....");
                IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
                if (selection.getFirstElement() instanceof Package) {
                    check = ((Package)selection.getFirstElement()).isReadyToShip();
                    System.out.print("IT'S A PACKAGE....");
                    // evaluate all @CanExecute methods
                    broker.post(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC, check);
                }
                System.out.print("\n");
            }
        });
    }

执行装运的处理程序是

public class ShipmentHandler {
    @Execute
    public void execute(Shell shell) {
        //TODO
    }
    
    @Inject
    @Optional
    @CanExecute
    public boolean canExecute(@UIEventTopic(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC) boolean checkPackageReady) {
        System.out.println("Inside canExecute method... " + checkPackageReady);
        if (checkPackageReady)
            return true;
        return false;
    }
}

但是按钮永远不会被禁用,即使 @canExecute 方法 returns 为 false,例如,在单击包 88、89 和 110 和 112 后显示以下控制台输出,按钮始终启用:

Selection listener  PACKAGE: 88...true
Inside canExecute method... true
Selection listener  PACKAGE: 89...false
Inside canExecute method... false
Selection listener  PACKAGE: 110...false
Inside canExecute method... false
Selection listener  PACKAGE: 112...true
Inside canExecute method... true

我不认为你可以这样混合使用 @CanExecute@UIEventTopic。无论如何 UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC 是一个相当特殊的话题,不打算这样处理。

broker.post(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC 的参数应该是元素 id,UIEvents.ALL_ELEMENT_IDorg.eclipse.e4.ui.workbench.Selector,没有别的。该参数选择更新哪些处理程序。

因此您不能将 'checkPackageReady' 值直接传递给处理程序,您将不得不使用一些其他机制 - 例如视图和处理程序都可以注入的模型对象。

您还可以使用 ESelectionService 设置零件的当前选择,然后您可以在处理程序中访问此信息:

查看部分:

@Inject 
ESelectionService selectionService;

...

public void widgetSelected(SelectionEvent e)
{
  selectionService.setSelection(viewer.getStructuredSelection());

  broker.post(UIEvents.REQUEST_ENABLEMENT_UPDATE_TOPIC, ... selector);
}

可以执行:

@CanExecute
public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION) IStructuredSelection selection, @Named(IServiceConstants.ACTIVE_PART)  MPart part)
{
  // TODO check part is your part
  // TODO check the selection
}