У меня есть пользовательский элемент управления, который я могу перетаскивать в режиме Form1.cs [Design]. Дизайнер автоматически сгенерирует код для этого пользовательского элемента управления в Form1.Designer.cs
Что бы я хотел получить, так это то, что в данный момент я добавляю пользовательский элемент управления в форму, перетаскивая его, и я не создаю в своем Form.cs код, указывающий на свойства и элементы управления этого пользовательского элемента управления.
Пример пользовательского контроля:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public string TextInTextBox
{
get { return textBox1.Text; }
set { textBox1.Text = value; }
}
}
Так что теперь, когда я перетащить его на форму в Form1.cs [Design]. Я не буду использовать часть кода, подобного этому, в моем Form1.cs:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
AddText();
}
// this code below to be auto-generated
private void AddText()
{
userControl11.TextInTextBox = "";
}
}
Я думаю, что я должен искать что-то вроде наследования или интерфейса, но я бы хотел, чтобы это происходило для каждого экземпляра этого пользовательского элемента управления. Если бы кто-то мог указать мне направление, что искать это было бы здорово. Благодарю.
Всего 1 ответ
Обычно вам не нужно генерировать код вручную, когда вы хотите назначить свойство при удалении элемента управления из панели инструментов, например, вы можете легко сделать это:
public MyUserControl()
{
InitializeComponent();
MyTextProperty = "Something";
}
И он будет сериализован автоматически.
Но есть и другие варианты для более сложных требований. Если вы знаете, какие у вас есть варианты, вы можете выбрать их в зависимости от ваших требований. Вот несколько вариантов:
ToolboxItem
, оно перезапишет значение, которое вы назначаете в конструкторе. Load
формы и инициализируйте свойство там. Это полезно для сложных генераций кода, например, когда вы отбрасываете источник данных, он генерирует некоторый код для загрузки данных и добавляет к загрузке событие формы. Предполагая, что вы присвоили Something
MyTextProperty
в конструкторе, затем, когда вы MyTextProperty
управления в форме, вот что будет сгенерировано в designer.cs:
this.myUserControl1.MyTextProperty = "Something";
Если вы используете решение ToolboxItem
для назначения Something else
свойству, результат в файле designer.cs будет:
this.myUserControl1.MyTextProperty = "Something else";
И если вы решите использовать третий вариант и сгенерировать код обработчика событий, результат в файле designer.cs будет:
this.Load += new System.EventHandler(this.Form1_Load);
и результат в файле cs будет:
private void Form1_Load(object sender, EventArgs e)
{
myUserControl1.MyTextProperty = "Even something else!";
}
пример
Вот полный код MyUserControl
, MyUserControlToolboxItem
и MyUserControlDesigner
. Вы можете комментировать атрибуты Designer
и / или ToolboxItem
закрывать все дизайнеры, очищать и перестраивать решение, а также ToolboxItem
экземпляр элемента управления в форме, чтобы увидеть, как он работает.
using System.CodeDom;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.Design;
[Designer(typeof(MyUserControlDesigner))]
[ToolboxItem(typeof(MyUserControlToolBoxItem))]
public partial class MyUserControl : UserControl
{
public MyUserControl()
{
InitializeComponent();
}
public string MyTextProperty { get; set; } = "Something";
}
public class MyUserControlToolBoxItem : ToolboxItem
{
protected override IComponent[] CreateComponentsCore(IDesignerHost host)
{
IComponent[] componentsCore = base.CreateComponentsCore(host);
if (componentsCore != null && componentsCore.Length > 0
&& componentsCore[0] is MyUserControl)
(componentsCore[0] as MyUserControl)
.MyTextProperty = "Something else"; ;
return componentsCore;
}
}
public class MyUserControlDesigner : ControlDesigner
{
public override void InitializeNewComponent(IDictionary defaultValues)
{
base.InitializeNewComponent(defaultValues);
var component = Control;
var eventBindingService = (IEventBindingService)this.GetService(
typeof(IEventBindingService));
var componentChangeService = (IComponentChangeService)this.GetService(
typeof(IComponentChangeService));
var designerHostService = (IDesignerHost)GetService(typeof(IDesignerHost));
var rootComponent = designerHostService.RootComponent;
var uiService = (IUIService)GetService(typeof(IUIService));
var designerTransaction = (DesignerTransaction)null;
try
{
designerTransaction = designerHostService.CreateTransaction();
var e = TypeDescriptor.GetEvents(rootComponent)["Load"];
if (e != null)
{
var methodName = "";
var eventProperty = eventBindingService.GetEventProperty(e);
if (eventProperty.GetValue(rootComponent) == null)
{
methodName = eventBindingService
.CreateUniqueMethodName(rootComponent, e);
eventProperty.SetValue(rootComponent, methodName);
}
else
methodName = (string)eventProperty.GetValue(rootComponent);
var code = this.GetService(typeof(CodeTypeDeclaration))
as CodeTypeDeclaration;
CodeMemberMethod method = null;
var member = code.Members.Cast<CodeTypeMember>()
.Where(x => x.Name == methodName).FirstOrDefault();
if (member != null)
{
method = (CodeMemberMethod)member;
method.Statements.Add(
new CodeSnippetStatement($"{Control.Name}" +
$".MyTextProperty = "Even something else!";"));
}
componentChangeService.OnComponentChanged(rootComponent,
eventProperty, null, null);
eventBindingService.ShowCode(rootComponent, e);
}
designerTransaction.Commit();
}
catch (System.Exception ex)
{
if (designerTransaction != null)
designerTransaction.Cancel();
uiService.ShowError(ex);
}
}
}