Мы можем строить элементы с использованием виджета невизуального класса. Пора сделать визуальный элемент с использованием класса .NET Framework наследника System.Windows.Forms.Control. На этот раз, для примера, мы выберем MaskedTextBox класс. Элемент управления MaskedTextBox по сути представляет обычное текстовое поле ввода. Однако он позволяет контролировать ввод пользователя и проверять его автоматически на наличие ошибок. Добавим к нашему проекту новый файл класса с именем HCMaskedTextBox.cs. Только в качестве шаблона кода выберем Component Class:
Добавим ссылку на сборку System.Windows.Forms.dll:
Заменим содержимое шаблона в файле HCMaskedTextBox.cs следующим кодом:
using HiAsm;
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace ElementVirtual
{
public partial class HCMaskedTextBox : ElementTplWinControl
{
public HCMaskedTextBox(PackElement pe, SDK sdk, int x, int y) : base(pe, sdk, x, y)
{
flag |= (int)(ElementFlag.IS_VIRTUAL | ElementFlag.IS_SYSTEM);
InitializeComponent();
}
}
}
[About(version = "1.0", author = "Developer Name", mail = "developer@mail.net")]
[DesignTimeVisible(true)]
[ToolboxBitmap(typeof(HCMaskedTextBox), "Resources.MaskedTextBox.ico")]
[Type("HCMaskedTextBox", "String editor with input validation", tab = "Controls", group = "Common", category = "Common", inherit = "TplWinControl")]
[Edit(Class = "System.Windows.Forms.MaskedTextBox")]
[Assembly("System.Windows.Forms.dll=System.Windows.Forms.MaskedTextBox")]
[Install("_base", "Simple visual demo", "Controls")]
[Property("Width", "Sets the width of the control. ARG(Int32)", DataType.data_int, group = "Geometry", makemethod = true, value = "100")]
[Property("Height", "Sets the height of the control. ARG(Int32)", DataType.data_int, group = "Geometry", makemethod = true, value = "20")]
[Property("TextMaskFormat", "Sets a value that determines whether literals and prompt characters are included in the formatted string. ARG(MaskFormat)", DataType.data_comboEx, group = "Behavior", makemethod = true, value = "1", list = "IncludePrompt,IncludeLiterals,IncludePromptAndLiterals,ExcludePromptAndLiterals")]
[Property("Mask", "Sets the input mask to use at run time. ARG(String)", DataType.data_str, group = "Behavior", doubleopen = true)]
[Point("onMaskInputRejected", "Occurs when the user's input or assigned character does not match the corresponding format element of the input mask. ARG(MaskInputRejectedEventArgs)", DataType.data_object, PointType.pt_event)]
[Point("Text", "Returns the text as it is currently displayed to the user. ARG(String)", DataType.data_str, PointType.pt_var)]
private MaskedTextBox control;
public override void prepareForRun(ref Element parent)
{
base.prepareForRun(ref parent);
this.control = this.widget as MaskedTextBox;
this.control.MaskInputRejected += (s, e) =>
{
TData dt = new TData(e);
on_event(getPointByName("onMaskInputRejected"), ref dt);
};
}
Компилируем сборку и добавляем новый элемент на панель элементов, открыв файл сборки в программе:
Собираем простую тестовую схему проекта Core (Шаблоны):
Add(hcTplForm,2953706,21,105)
{
StartPosition=4
}
Add(Example,2,126,105)
{
Greeting="Hello!"
link(onGreeting,7:doWork2,[])
link(Data,5:Text,[])
}
Add(hcTplButton,3,70,105)
{
Left=36
Top=23
link(onClick,2:doSayHello,[])
}
Add(hcMessage,4,182,105)
{
link(Caption,2:Greeting,[(195,91)(167,91)(167,150)(132,150)])
}
Add(HubEx,7,168,105)
{
link(onEvent,4:doMessage,[])
}
Add(HCMaskedTextBox,5,126,49)
{
Left=97
Top=23
Mask="00/00/0000"
link(onMaskInputRejected,7:doWork1,[(172,55)])
}


Теперь сделаем скрипт проекта Windows Forms в файле wfHCMaskedTextBox.cs и добавим его в ресурсы сборки:
//css_pc wfPrecompiler.cs;
public class HCMaskedTextBox : WinElement
{
public override bool init(object entry)
{
Debug.WriteLine("{0}.init()".fString(this.codename));
@this.obj = sys.add_widget(this);
Task t = new Task(() =>
{
sys.event_imp(this, "onMaskInputRejected", null, "e");
});
this.taskManager.Add(new TaskState(t, "onMaskInputRejected"));
return base.init(this);
}
}
Add(EntryPoint,2953706,21,105)
{
StartPosition=1
Point(onError)
link(onError,2:doMessage,[])
}
Add(hcMessage,2,70,119)
{
Caption="Error"
Icon=1
}
Add(Example,7,175,119)
{
Greeting="Hello!"
link(onGreeting,10:doWork2,[])
link(Data,11:Text,[])
}
Add(hcTplButton,8,119,119)
{
Left=36
Top=23
link(onClick,7:doSayHello,[])
}
Add(hcMessage,9,231,119)
{
link(Caption,7:Greeting,[(244,105)(216,105)(216,164)(181,164)])
}
Add(HubEx,10,217,119)
{
link(onEvent,9:doMessage,[])
}
Add(HCMaskedTextBox,11,175,63)
{
Left=97
Top=23
Mask="00/00/0000"
link(onMaskInputRejected,10:doWork1,[(221,69)])
}


Можете скачать полный код проекта: MyElementCore.zip