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 ответ:
Убедитесь, что при редактировании кода, созданного дизайнером, вы редактируете его таким образом, чтобы он мог прочитать его и повторно сериализовать. В этой ситуации дизайнер искал:
control.Click += new System.EventHandler(this.methodname)
Но я давал его:
И хотя он работал просто отлично, когда конструктор был отредактирован и повторно сериализован, он не мог разобрать, что я сделал, и просто удалил его.
control.Click += this.methodname
Я обнаружил свою ошибку, заставив дизайнера генерировать событие, и именно тогда я заметил, что код, который он создал, и то, что я ему давал, были другими. Если у вас есть подобные проблемы, то я предлагаю попросить дизайнера создать что-то похожее на то, что вы делаете, а затем использовать это в качестве руководства.