.netwinformscontrolsdesign-time

Get design-time notifications when a Control referenced in another control is removed from the Form


I have a custom control with a property allowing to select another control of a specific type on a form. For simplicity, let it be TextBox controls.

The property of my custom control looks like this:

private TextBox _targetControl;

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

Is there a way to get a notification in my custom control when the selected target control is removed from the form at design time? Note that the target control can be located in a container such as Panel (i.e. it is not an item of the form's Controls collection).


Solution

  • To receive notifications when a Component is added, removed, renamed or otherwise changed at Design-Time, you can call the [Component].GetService() method to initialize an IComponentChangeService on the current Site.

    This Interface allows to subscribe to events, as IComponentChangeService.ComponentRemoved, that are raised when something happens to a Component in the Form Designer.

    For example, when this UserControl is sited, it subscribes to the ComponentRemoved and ComponentRemoving events, to verify whether the event is related to the Control referenced by the TargetControl Property:

    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;
    }