我有一个 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,从而触发我的处理程序。更有趣的是——第一次点击确实改变了复选框的状态,但它并没有触发事件。
任何帮助,将不胜感激。