我有一个自定义控件,其属性允许在窗体上 Select 另一个特定类型的控件.为简单起见,我们将其设为TextBox控件.

我的自定义控件的属性如下所示:

private TextBox _targetControl;

public TextBox TargetControl
{
    get {return _targetControl;}
    set {_targetControl = value;}
}

当选定的目标控件在设计时从窗体中移除时,有没有办法在我的自定义控件中收到通知?请注意,目标控件可以位于诸如Panel之类的容器中(即它不是窗体的Controls集合的项).

推荐答案

若要在设计时添加、移除、重命名或以其他方式更改组件时接收通知,可以调用[Component].GetService()方法来初始化当前站点上的IComponentChangeService.

此接口允许订阅事件,如IComponentChangeService.ComponentRemoved,当something happens引发到窗体设计器中的组件时会引发这些事件.

例如,当定位此UserControl时,它订阅ComponentRemovedComponentRemoving事件,以验证该事件是否与TargetControl属性引用的控件相关:

public partial class UCComponentsChange : UserControl {
    private IComponentChangeService componentChangeService;

    public UCComponentsChange() =>InitializeComponent();

    private TextBox _targetControl = null;
    public TextBox TargetControl {
        get => _targetControl;
        set => _targetControl = value;
    }

    public override ISite Site {
        get => base.Site;
        set {
            base.Site = value;
            RegisterComponentsChangeNotifications();
        }
    }

    private void RegisterComponentsChangeNotifications() {
        if (componentChangeService != null) {
            componentChangeService.ComponentRemoving -= NotifyComponentRemoving;
            componentChangeService.ComponentRemoved -= NotifyComponentRemoved;
        }

        componentChangeService = GetService(typeof(IComponentChangeService)) as IComponentChangeService;
        if (componentChangeService != null) {
            componentChangeService.ComponentRemoving += NotifyComponentRemoving;
            componentChangeService.ComponentRemoved += NotifyComponentRemoved;
        }
    }

    private void NotifyComponentRemoving(object sender, ComponentEventArgs e) {
        if (IsTargetControlAffected(e.Component)) {
            // Our Control is being removed
        }
    }

    private void NotifyComponentRemoved(object sender, ComponentEventArgs e) {
        if (IsTargetControlAffected(e.Component)) {
            // Our Control has been removed. Set the reference to null 
            TargetControl = null;
        }
    }

    private bool IsTargetControlAffected(IComponent component) =>
        _targetControl != null && _targetControl == component;
}

.net相关问答推荐

API响应返回null错误. NET MAUI

删除数据库项目中的表

安装特定主要版本的DotNet SDK最新版本

[x.x.x,)在Packages.lock.json依赖项中是什么意思?

EGC / 文本元素上的 .NET String.Split

Dictionary.FirstOrDefault() 如何判断是否找到了结果

无法解析此引用.找不到程序集

如何创建 LINQ to SQL 事务?

在 .NET 反射中使用 GetProperties() 和 BindingFlags.DeclaredOnly

如何在 C# 中创建表达式树来表示String.Contains("term")?

比较 C# 中的字符串和对象

String 是原始类型吗?

日期时间是什么意思?在 C# 中是什么意思?

在 .NET Core RC2 中构建 .exe 文件

监听依赖属性的变化

.NET 的黄瓜替代品

判断 .NET 中的目录和文件写入权限

绑定在代码隐藏中定义的对象

WinForms 中的模型视图演示者

浮动与双重性能