Rust Druid框架下Controller正确忽略非合规输入update的实现方法
问题原因
- 当前实现触发冻结的核心原因是:非法输入触发时完全跳过了
child.update调用,导致TextBox内部维护的光标位置、输入缓存等状态和外部绑定的data字段失去同步,控件无法继续响应后续交互。 - 直接传入old_data调用update的方案无效,是因为此时外部关联的data已经被更新为非法值,仅修改子控件更新的入参只会让内外状态进一步不一致,才会出现非法字符残留在输入框的问题。
正确实现方案
当检测到输入非法时,需要先主动将外部状态重置为上一个合法值,再正常调用子控件的update方法,保证内外状态完全同步:
struct NumericOnly; impl Controller<String, TextBox<String>> for NumericOnly { fn update(&mut self, child: &mut TextBox<String>, ctx: &mut UpdateCtx, old_data: &String, data: &String, env: &Env) { let is_valid = data.chars().enumerate().all(|(idx, chr)| { chr.is_numeric() || (chr == '-' && idx == 0) }); if !is_valid { // 重置外部状态为上一个合法值 ctx.set_data(old_data.clone()); // 用重置后的合法值同步更新子控件 child.update(ctx, old_data, old_data, env); return; } // 合法输入正常走更新逻辑 child.update(ctx, old_data, data, env); } }
补充优化提示
如果不需要支持负数输入,直接使用Druid TextBox原生提供的过滤方法更简洁,不需要自定义Controller:
let numeric_textbox = TextBox::new() .with_filter(char::is_numeric);
内容的提问来源于stack exchange,提问作者Nikolai Savulkin
相关产品推荐
相关产品推荐

