如何在eclipse中使用数据绑定验证输入并防止保存操作?

时间:2015-06-26 12:44:22

标签: eclipse validation data-binding

我想创建输入表单来验证用户输入并防止模型与无效数据一起保存。我一直在使用数据绑定,但是我的实现并不像我想的那样直观。

想象一下包含' 123'的输入。并且值不能为空。用户逐个删除字符直到空。数据绑定验证器显示错误修饰。

但是,如果用户保存表单并重新加载,那么' 1'显示在字段中 - 即最后一个有效输入。数据绑定不会将无效值传输到模型中。

我有一个ChangeListener但是在数据绑定之前调用它,所以此时没有检测到无效状态。

我希望错误显示在UI中,但模型仍然有效(已经是这样)。此外,只要UI包含错误,就不可能保存模型。

/**
 * Bind a text control to a property in the view model
 **/
protected Binding bindText(DataBindingContext ctx, Control control,
        Object viewModel, String property, IValidator validator)
{
    IObservableValue value = WidgetProperties.text(SWT.Modify).observe(
            control);
    IObservableValue modelValue = BeanProperties.value(
            viewModel.getClass(), property).observe(viewModel);
    Binding binding = ctx.bindValue(value, modelValue, getStrategy(validator), null);
    binding.getTarget().addChangeListener(listener);
    ControlDecorationSupport.create(binding, SWT.TOP | SWT.LEFT);

    return binding;
}

private UpdateValueStrategy getStrategy(IValidator validator)
{
    if (validator == null)
        return null;

    UpdateValueStrategy strategy = new UpdateValueStrategy();
    strategy.setBeforeSetValidator(validator);
    return strategy;
}

private IChangeListener listener = new IChangeListener()
{
    @Override
    public void handleChange(ChangeEvent event)
    {
    // notify all form listeners that something has changed     
    }
};

/**
 * Called by form owner to check if the form contains valid data e.g. before saving
 **/
public boolean isValid()
{
    System.out.println("isValid");
    for (Object o : getDataContext().getValidationStatusProviders())
    {
        ValidationStatusProvider vsp = (ValidationStatusProvider) o;
        IStatus status = (IStatus)vsp.getValidationStatus()
                .getValue();
        if (status.matches(IStatus.ERROR))
            return false;
    }
    return true;
}

2 个答案:

答案 0 :(得分:2)

你最好的选择是避开ChangeListener - 正如你所发现的那样,他们的执行顺序要么未定义,要么在这种情况下没有帮助。

相反,你想要尽可能长时间地坚持'可观察'而不是'听众'模式。如前所述,创建AggregateValidationStatus以收听DataBindingContext的整体状态,其效果与现有代码类似。

然后你可以直接听(如下所示)来影响保存能力,或者你甚至可以将它绑定到另一个bean。

IObservableValue statusValue = new AggregateValidationStatus(dbc, AggregateValidationStatus. MAX_SEVERITY);

statusValue.addListener(new IValueChangeListener() {
    handleValueChange(ValueChangeEvent event) {
        // change ability to save here...
    }
});

答案 1 :(得分:1)

您可以使用AggregateValidationStatus来观察汇总验证状态:

IObservableValue value = new AggregateValidationStatus(bindContext.getBindings(),
                                 AggregateValidationStatus.MAX_SEVERITY);

您可以将此绑定到接受IStatus参数的内容,并且每次验证状态更改时都会调用它。