如何在运行时动态命名变量以识别循环创建的Entry并解决事件绑定异常
动态标识Entry控件的解决方案
不需要在运行时动态生成变量名,直接用集合存储所有Entry实例即可,后续通过索引就能精准定位到任意指定的Entry:
// 先定义集合存储所有创建的Entry实例 List<Entry> entries = new List<Entry>(); for(int i = 0; i < list.Count; i++) { Entry entry = new Entry(){ Placeholder = "Entry number" + i.ToString() }; entries.Add(entry); // 此处可自行添加把Entry挂载到布局容器的逻辑,比如stackLayout.Children.Add(entry); }
后续需要操作指定Entry时,直接用索引取值即可,比如给第2个Entry设置焦点:entries[1].Focus()。
事件总是触发最后一个Entry的解决方案
这是C#闭包捕获循环变量的经典问题:for循环的迭代变量i属于整个循环的全局作用域,lambda表达式捕获的始终是同一个i变量,循环执行结束后i的值为list.Count,所以事件触发时取到的永远是最后一个元素。
有两种修复方案可选:
方案1:循环内定义临时变量存储当前索引
在循环内部定义局部临时变量,每次迭代的临时变量属于独立作用域,不会被后续迭代覆盖:
for(int i = 0; i < list.Count; i++) { // 新增循环内临时变量存储当前迭代索引 int tempIndex = i; entries[tempIndex].Completed += (s, e) => { if (!entries[tempIndex].Text.Contains("\u00b2")) { entries[tempIndex].Text += "\u00b2"; } }; entries[tempIndex].Focus(); }
方案2:直接用事件的sender参数(更稳妥)
事件的sender参数本身就是触发当前事件的Entry实例,不需要依赖索引取值,完全不会出现匹配错误的问题:
for(int i = 0; i < list.Count; i++) { entries[i].Completed += (s, e) => { Entry currentEntry = (Entry)s; if (!currentEntry.Text.Contains("\u00b2")) { currentEntry.Text += "\u00b2"; } }; entries[i].Focus(); }
内容的提问来源于stack exchange,提问作者techie
相关产品推荐
相关产品推荐

