WinForms Designer удаление событий при изменении элемента управления


Edit: я нашел проблему и опубликовал ответ ниже!

У меня есть несколько пользовательских элементов управления в WinForms, и я получаю проблему, когда в моей форме, когда я изменяю элемент управления в конструкторе (например, перемещая его на один пиксель, а затем перемещая его обратно), каждое событие, которое применялось к моим элементам управления, удаляется из кода конструктора.

Например, с помощью моей пользовательской кнопки я не делаю ничего особенного для события Click. Я даже не прикасаюсь к этому свойству в класс, в котором я унаследовал класс WinForms Button, но при изменении любого элемента управления в моей форме событие buttons click удаляется.

Я не смог найти ничего, связанного с удалением событий дизайнером в интернете, и я не вижу в своем коде ничего, что могло бы вызвать такую вещь.

Вот код для пользовательской кнопки, которая у меня есть, если это помогает:

CustomVisualButton.cs

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;

namespace CustomVisual {

    [Designer( typeof( CustomVisualControlDesigner ) )]
    public class CustomVisualButton : Button, CustomVisualControlInterface {

        private Boolean _IsHovering = false;

        #region Properties

        [DesignerSerializationVisibility( DesignerSerializationVisibility.Hidden ), Browsable( false )]
        public override Font Font {
            get {
                return base.Font;
            }
            set {
                base.Font = value;
            }
        }

        #endregion

        #region Constructor

        public CustomVisualButton( ) {

            DoubleBuffered = true;
            Font = CustomVisualPalette.DefaultFont;
            SetStyle( ControlStyles.UserPaint, true );
            SetStyle( ControlStyles.SupportsTransparentBackColor, true );
        }

        #endregion

        #region Overrides

        protected override void OnMouseEnter( EventArgs Args ) {

            base.OnMouseEnter( Args );
            _IsHovering = true;
            Cursor = Cursors.Hand;
        }

        protected override void OnMouseLeave( EventArgs Args ) {

            base.OnMouseLeave( Args );
            _IsHovering = false;
            Cursor = Cursors.Default;
        }

        protected override void OnPaint( PaintEventArgs Args ) {
            // long paint method
        }

        protected override void OnResize( EventArgs Args ) {

            base.OnResize( Args );

            if ( CustomVisualPalette.FORCE_HEIGHT > 0 ) {

                Height = CustomVisualPalette.FORCE_HEIGHT;
            }
        }

        #endregion

    }

}

CustomVisualControlInterface.cs

namespace CustomVisual {

    public interface CustomVisualControlInterface {
    }

}

CustomVisualControlDesigner.cs

using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Drawing;
using System;

namespace CustomVisual {


    public class CustomVisualControlDesigner : ControlDesigner {

        private DesignerActionListCollection _ActionLists;

        public override DesignerActionListCollection ActionLists {
            get {
                if ( null == _ActionLists ) {
                    _ActionLists = new DesignerActionListCollection( );
                    _ActionLists.Add( new CustomVisualControlActionList( this.Component ) );
                }
                return _ActionLists;
            }
        }

    }

    public class CustomVisualControlActionList : DesignerActionList {

        private Control _Control;
        private DesignerActionUIService _Service = null;

        public CustomVisualControlInterface AlignSubject { get; set; }

        public CustomVisualControlActionList( IComponent Component )
            : base( Component ) {

            _Control = Component as Control;
            _Service = GetService( typeof( DesignerActionUIService ) ) as DesignerActionUIService;

        }

        public void RefreshDesigner( ) {

            _Service.HideUI( _Control );
            _Service.Refresh( _Control );
            _Service.ShowUI( _Control );
        }

        public Int32 SyncHeight( Control Source, Control Destination ) {
            // vertical alignment for elements of possible different height
        }

        public void MatchWidth( ) {
            // makes element width same as subject width
        }

        public void PlaceUnder( ) {
            // places element under subject
        }

        public void PlaceCloseUnder( ) {
            // places element close under subject
        }

        public void PlaceRight( ) {
            // places element right of subject
        }

        public void PlaceCloseRight( ) {
            // places element close right of subject
        }

        public void PlaceAbove( ) {
            // places element above subject
        }

        public void PlaceLeft( ) {
            // places element left of subject
        }

        public void AnchorType1( ) {
            // code to align to certain spot
        }

        public override DesignerActionItemCollection GetSortedActionItems( ) {

            DesignerActionItemCollection Items = new DesignerActionItemCollection( );
            Items.Add( new DesignerActionPropertyItem( "AlignSubject", "Subject", "alignment" ) );
            Items.Add( new DesignerActionMethodItem( this, "MatchWidth", "match width", "alignment" ) );
            Items.Add( new DesignerActionMethodItem( this, "PlaceAbove", "place above", "alignment" ) );
            Items.Add( new DesignerActionMethodItem( this, "PlaceRight", "place right", "alignment" ) );
            Items.Add( new DesignerActionMethodItem( this, "PlaceCloseRight", "place close right", "alignment" ) );
            Items.Add( new DesignerActionMethodItem( this, "PlaceUnder", "place under", "alignment" ) );
            Items.Add( new DesignerActionMethodItem( this, "PlaceCloseUnder", "place close under", "alignment" ) );
            Items.Add( new DesignerActionMethodItem( this, "PlaceLeft", "place left", "alignment" ) );
            Items.Add( new DesignerActionMethodItem( this, "AnchorType1", "anchor type 1", "anchors" ) );
            return Items;

        }

    }
}
1 2

1 ответ:

Убедитесь, что при редактировании кода, созданного дизайнером, вы редактируете его таким образом, чтобы он мог прочитать его и повторно сериализовать. В этой ситуации дизайнер искал:

control.Click += new System.EventHandler(this.methodname)

Но я давал его:

control.Click += this.methodname

И хотя он работал просто отлично, когда конструктор был отредактирован и повторно сериализован, он не мог разобрать, что я сделал, и просто удалил его.

Я обнаружил свою ошибку, заставив дизайнера генерировать событие, и именно тогда я заметил, что код, который он создал, и то, что я ему давал, были другими. Если у вас есть подобные проблемы, то я предлагаю попросить дизайнера создать что-то похожее на то, что вы делаете, а затем использовать это в качестве руководства.