1

我有一个 GWT DataGrid,在标题中有一个 CheckBox 来选择/取消选择网格中的所有行。

CheckBox Header 的代码如下:

    private class CheckboxHeader extends Header<Boolean> implements HasValue<Boolean> {

    private boolean checked;
    private HandlerManager handlerManager;

    /**
     * An html string representation of a checked input box.
     */
    private final SafeHtml INPUT_CHECKED = SafeHtmlUtils.fromSafeConstant("<input type=\"checkbox\" tabindex=\"-1\" checked/>");
    /**
     * An html string representation of an unchecked input box.
     */
    private final SafeHtml INPUT_UNCHECKED = SafeHtmlUtils.fromSafeConstant("<input type=\"checkbox\" tabindex=\"-1\"/>");

    @Override
    public void render(Context context, SafeHtmlBuilder sb) {
        if (Boolean.TRUE.equals(this.getValue())) {
            sb.append(INPUT_CHECKED);
        } else {
            sb.append(INPUT_UNCHECKED);
        }
    };

    public CheckboxHeader() {
        super(new CheckboxCell(true, false));
        checked = true;
    }

    // This method is invoked to pass the value to the CheckboxCell's render method
    @Override
    public Boolean getValue() {
        return checked;
    }

    @Override
    public void onBrowserEvent(Context context, Element elem, NativeEvent nativeEvent) {
        int eventType = Event.as(nativeEvent).getTypeInt();
        if (eventType == Event.ONCHANGE) {
            nativeEvent.preventDefault();
            // use value setter to easily fire change event to handlers
            setValue(!checked, true);
        }
    }

    @Override
    public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Boolean> handler) {
        return ensureHandlerManager().addHandler(ValueChangeEvent.getType(), handler);
    }

    @Override
    public void fireEvent(GwtEvent<?> event) {
        ensureHandlerManager().fireEvent(event);
    }

    @Override
    public void setValue(Boolean value) {
        setValue(value, true);
    }

    @Override
    public void setValue(Boolean value, boolean fireEvents) {
        checked = value;
        if (fireEvents) {
            ValueChangeEvent.fire(this, value);
        }
    }

    private HandlerManager ensureHandlerManager() {
        if (handlerManager == null) {
            handlerManager = new HandlerManager(this);
        }
        return handlerManager;
    }
}

因此,我将 Header 添加到网格中,并在其中添加一个ValueChangeHandler以对网格的每一行中的单个 CheckBox 单元格进行实际选择/取消选择。这一切都有效。

每个CheckBoxCell都有一个字段更新器,并且在每次更新时,它都会遍历网格中的每个项目以查看它们是否都被选中,并更新标题复选框。如果至少有一个未选中,则标题复选框将未选中。我调用setValue()标题复选框,然后调用redrawHeaders()整个网格。这也有效。

不起作用的是 - 在以编程方式更改标题复选框的“状态”之后,需要单击两次才能再次触发它的内部 setValue,从而触发我的处理程序。更有趣的是——第一次点击确实改变了复选框的状态,但它并没有触发事件。

任何帮助,将不胜感激。

4

1 回答 1

1

你是如何自己构建 CheckboxCells 的?我遇到了一列复选框“吃”点击的类似问题,解决方案是调用CheckboxCell cell = new CheckboxCell(true,true)该单元格,然后将该单元格传递到该列的构造函数中。

于 2013-08-02T20:35:32.790 回答