WPF如何引用并操作动态生成的自定义FixerBox控件
问题根因
FindName失效的核心原因是动态生成的控件不会自动注册到当前逻辑树的名称范围,即便你给控件的Name属性赋值,未显式注册的情况下FindName也无法检索到对应控件。
最优实现方案
你代码中已经定义了fixerBoxes字典来存储所有生成的FixerBox实例,直接用这个字典操作控件是效率最高、实现最简单的方案,完全不需要调用查找方法:
// 直接通过key获取对应控件,不会返回null FixerBox f1box = fixerBoxes["F1"]; StatusBox.Text += "Tags are:"+ f1box.FixerTags;
注意把fixerBoxes定义为MainWindow的类级成员变量,保证类内所有方法都可以访问。
若需使用FindName的兼容方案
如果确实需要使用FindName方法检索控件,在添加控件时显式注册到名称范围即可:
foreach (string key in fixNames) { var temp = fixers.GetFix(key); temp["Name"] = key; fixerBoxes[key] = new FixerBox(temp); // 给控件的Name属性赋值 fixerBoxes[key].Name = key; FixersArea.Children.Add(fixerBoxes[key]); // 把控件注册到WrapPanel的名称范围 FixersArea.RegisterName(key, fixerBoxes[key]); }
对应需求的实现方式
- 读取/设置控件状态:遍历
fixerBoxes.Values即可批量操作所有控件,单个控件直接用key索引取值操作即可,保存/加载配置时直接读写控件的对应属性即可。 - 筛选显示隐藏控件:遍历字典判断筛选条件,设置控件的
Visibility属性即可,示例如下:
// 按标签筛选示例:只显示带#Rage标签的控件 foreach (var box in fixerBoxes.Values) { box.Visibility = box.FixerTags.Contains("#Rage") ? Visibility.Visible : Visibility.Collapsed; }
- 主窗口响应控件事件:在
FixerBox自定义控件中声明自定义事件,生成控件时统一订阅即可,示例如下:
// 生成控件时订阅事件 fixerBoxes[key] = new FixerBox(temp); fixerBoxes[key].FixerClicked += FixerBox_FixerClicked; // 主窗口中的事件处理方法 private void FixerBox_FixerClicked(object sender, EventArgs e) { var clickedBox = sender as FixerBox; // 处理对应逻辑 }
内容的提问来源于stack exchange,提问作者not_a_generic_user
相关产品推荐
相关产品推荐

