Pieter Geerkens
Pieter Geerkens

Reputation: 11893

How to connect Events and their Handlers (from Form sub-components) with Designer?

I have subclassed ToolStrip thus:

using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace PGNapoleonics.MapForm {
    public partial class DetailMapFormToolStrip : ToolStrip, IDisplayMenuOptions, ISupportInitialize {
        public DetailMapFormToolStrip() => InitializeComponent();
        public DetailMapFormToolStrip(IContainer container) { container.Add(this); InitializeComponent(); }

        public void BeginInit() { }
        public void EndInit() {
            MainMenuStrip.Visible = DesignMode;
            if (DesignMode) return;
        }

        /// <inheritdoc/>
        public event EventHandler<EventArgs>     HighlightFovChange;
        /// <inheritdoc/>
        public event EventHandler<EventArgs>     HighlightHexChange;
        /// <inheritdoc/>
        public event EventHandler<EventArgs>     HighlightUnitChange;
        /// <inheritdoc/>
        public event EventHandler<ZoomEventArgs> ZoomChange;

and placed an instance on my form as mapFormtoolStrip.

Then I created a state component with eventhandlers thus:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;

namespace PGNapoleonics.MapForm {

    public partial class GameDisplayState : Component, IGameDisplayState, ISupportInitialize {
        public GameDisplayState() => InitializeComponent();    
        public GameDisplayState(IContainer container) { container.Add(this); InitializeComponent(); }

        /// <inheritdoc/>
        public virtual void BeginInit() { }

        /// <inheritdoc/>
        public virtual void EndInit() { }

        /// <inheritdoc/>
        [Browsable(true)]
        public void HighlightFovChange(object sender, EventArgs e) { }

        /// <inheritdoc/>
        [Browsable(true)]
        public void HighlightHexChange(object sender, EventArgs e) { }

        /// <inheritdoc/>
        [Browsable(true)]
        public void HighlightUnitChange(object sender, EventArgs e) { }

        /// <inheritdoc/>
        [Browsable(true)]
        public void ZoomChange(object sender, ZoomEventArgs e) { }

instantiated on the form as gameDisplayState.

The whole compiles and displays fine in the designer as shown here:

enter image description here

However the Designer won't let me connect the eventhandlers from gameDisplayState to the events from mapFormToolStrip. The events from mapFormtoolStrip are visible in the designer, but gameDisplayState and its eventhandlers are not. When i attempt to manually type the appropriate reference (as for example gameDisplayState.HighlightFovChange) I get the message dialog:

enter image description here

enter image description here

Have I missed a step?

Or is this simply not possible?

The clean structure of keeping the plumbing connections in the Designer, away from the procedural code behind, quite appealed to me.

Upvotes: 0

Views: 44

Answers (1)

Pieter Geerkens
Pieter Geerkens

Reputation: 11893

In light of the comment above by Hans Passant:

Simply not possible.

the workaround seems to be:

    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);
        MenuStrip.Visible = DesignMode;
        if (DesignMode) return;

        ConnectEventRelays();
    }

    #region EventRelays
    /// <inheritdoc/>
    public event EventHandler<EventArgs>     HighlightFovChange;
    /// <inheritdoc/>
    public event EventHandler<EventArgs>     HighlightHexChange;
    /// <inheritdoc/>
    public event EventHandler<EventArgs>     HighlightUnitChange;
    /// <inheritdoc/>
    public event EventHandler<ZoomEventArgs> ZoomChange;

    [Browsable(true)]
    public void HighlightFovChangeRelay(object sender, EventArgs e) => HighlightFovChange?.Invoke(sender, e);

    [Browsable(true)]
    public void HighlightHexChangeRelay(object sender, EventArgs e) => HighlightHexChange?.Invoke(sender, e);

    [Browsable(true)]
    public void HighlightUnitChangeRelay(object sender, EventArgs e) => HighlightUnitChange?.Invoke(sender, e);

    [Browsable(true)]
    public void ZoomChangeRelay(object sender, ZoomEventArgs e) => ZoomChange?.Invoke(sender, e);

    protected virtual void ConnectEventRelays() {
        HighlightFovChange  += gameDisplayState.HighlightFovChange;
        HighlightHexChange  += gameDisplayState.HighlightHexChange;
        HighlightUnitChange += gameDisplayState.HighlightUnitChange;
        ZoomChange          += gameDisplayState.ZoomChange;
    }
    #endregion Event Relays

with the Designer capable only of connecting the events from mapFormToolStrip to handlers from `MapForm itself thus:

enter image description here

In light of the work required for ConnectEventRelays() this almost seems more worthwhile in code behind instead of the Designer.

Only available in WPF you say. Pity.

Upvotes: 1

Related Questions