首页 > 解决方案 > 如何将事件及其处理程序(来自表单子组件)与设计器连接?

问题描述

我因此将 ToolStrip 子类化:

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;

并在我的表单上放置了一个实例作为mapFormtoolStrip.

然后我创建了一个带有事件处理程序的状态组件,因此:

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) { }

在表单上实例化为gameDisplayState.

整个编译并在设计器中显示良好,如下所示:

在此处输入图像描述

但是,设计师不会让我将事件处理程序连接gameDisplayState到来自 mapFormToolStrip. 来自的事件mapFormtoolStrip在设计器中可见,但gameDisplayState其事件处理程序不可见。当我尝试手动输入适当的参考(例如gameDisplayState.HighlightFovChange)时,我收到消息对话框:

在此处输入图像描述

在此处输入图像描述

我错过了一步吗?

或者这根本不可能?

保持设计器中管道连接的简洁结构,远离背后的程序代码,非常吸引我。

标签: c#winforms

解决方案


根据Hans Passant的上述评论:

根本不可能。

解决方法似乎是:

    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

设计器只能将事件mapFormToolStrip从 `MapForm 本身连接到处理程序,因此:

在此处输入图像描述

鉴于此所需的工作ConnectEventRelays()几乎似乎更值得在代码后面而不是设计器中。

仅在您说的 WPF 中可用。遗憾。


推荐阅读