WPF/C#中如何为动态生成的自定义控件添加点击事件并访问其元素?
解决方案
方案1:自定义控件暴露公开事件(推荐,符合封装规范)
这是最优方案,控件内部只负责触发UI交互信号,业务逻辑完全交给外部实现,耦合度最低。
- 修改
FixerBox自定义控件代码,新增公开事件并触发:
public partial class FixerBox : UserControl { // 新增公开点击事件,外部直接绑定这个事件即可 public event EventHandler SwitchClicked; // 原有属性、构造函数、btnOn/btnOff方法保持不变... private void FixBtnBk_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // 触发外部绑定的事件,sender传递当前FixerBox实例,方便外部区分不同控件 SwitchClicked?.Invoke(this, EventArgs.Empty); e.Handled = true; } private void FixBtnDot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { FixBtnBk_MouseLeftButtonDown(sender, e); } }
- 主窗口绑定事件时直接绑定该公开事件即可,不需要访问控件内部元素:
public MainWindow() { InitializeComponent(); var fixNames = fixers.FixerNames(); foreach (string key in fixNames) { var temp = fixers.GetFix(key); temp["Name"] = key; fixerBoxes[key] = new FixerBox(temp); // 直接绑定公开事件 fixerBoxes[key].SwitchClicked += fixClick; FixersArea.Children.Add(fixerBoxes[key]); } }
你的fixClick方法不需要做任何修改,直接就能正常使用。
方案2:强制转换内部元素类型(不推荐,依赖内部UI结构)
你原来的代码报错是因为FindName返回的是object类型,需要显式转换为对应的UI元素类型才能访问事件:
public MainWindow() { InitializeComponent(); var fixNames = fixers.FixerNames(); foreach (string key in fixNames) { var temp = fixers.GetFix(key); temp["Name"] = key; fixerBoxes[key] = new FixerBox(temp); // 转换为实际的元素类型,这里假设FixBtnBk是Rectangle,FixBtnDot是Ellipse var btnBk = fixerBoxes[key].FindName("FixBtnBk") as System.Windows.Shapes.Rectangle; var btnDot = fixerBoxes[key].FindName("FixBtnDot") as System.Windows.Shapes.Ellipse; if (btnBk != null) btnBk.MouseLeftButtonDown += fixClick; if (btnDot != null) btnDot.MouseLeftButtonDown += fixClick; FixersArea.Children.Add(fixerBoxes[key]); } }
注意需要同步修改fixClick的参数和逻辑适配路由事件:
private void fixClick(object sender, MouseButtonEventArgs e) { StatusBox.Text = "CLICK WORKS"; // 从事件源的父级找到FixerBox实例 FixerBox whichFix = (FixerBox)((FrameworkElement)sender).TemplatedParent; if (whichFix.IsOn) { whichFix.btnOff(); } else { whichFix.btnOn(); } }
该方案缺点是如果后续你修改了控件内部的元素名称、类型,外部绑定代码会全部失效,维护成本更高。
内容的提问来源于stack exchange,提问作者not_a_generic_user
相关产品推荐
相关产品推荐

