Задача: немного изменить внешний вид и/или поведение существующего элемента управления Windows Forms. В теории все крайне просто для знакомых с основами объектно-ориентированного программирования людей - мы просто создаем класс-наследник для уже существующего элемента и добавляем новые свойства и метода или переопределяем существующие (для тонких изменений внешнего вида можно изменить работу функции отрисовки на экране). Например нам надо вводить числа, но клиенты очень не любят виде 0 для тех полей, где нет данных. Если возраст человека не указан, это еще не значит что возраст человека 0 лет. Таким образом числа надо вводить как текст (с NumericUpDown есть еще несколько мелких неудобств) автоматически проверяя на отсутствие бреда в пользовательском вводе и заменяя сохраненные в базе нули на пустые строки. Сделать это можно просто добавив пару функций к стандартному текстбоксу.
Поводом для создания это заметки стала небольшая порция шаманства, связанная с особенностями работы Visual Studio и Windows Forms - наследоваться надо не просто так, а выполнив ряд простых но несколько нелогичных шагов, согласно вот этому руководству.
Проще говоря:
1. К проекту добавляем новый элемента из пункта Add User Control
2. В появившемся далоговом окне выбрать Custom Control
3. В добавленном компоненте найти то место где описано наследование в духе
public partial class CustomControl1 : Control
и заменить базовый класс на нужный нам, например
public partial class TextBoxPlus : TextBox
Если пытаться выполнить наследование другим путем то мы можем получить ряд странных глюков, например вместо Control создать Component который будет виден только в дизайнере для других элементов управления и не виден в дизайнере форм.
Для решения приведенной в качестве примера задачи с TextBox можно добавить такие функции
public partial class TextBoxPlus : TextBox
{
public TextBoxPlus()
{
InitializeComponent();
}
public decimal ValueDecimal
{
get
{
decimal valueDecimal = 0;
if (Text != "")
{
try
{
valueDecimal = ConvertToDecimal(Text);
}
catch { }
}
return valueDecimal;
}
set
{
if (value == 0)
{
Text = "";
}
else
{
Text = value.ToString();
}
}
}
public bool ValueDecimalCorrect
{
get
{
bool correct = false;
try
{
decimal temp = ConvertToDecimal(Text);
correct = true;
}
catch { }
return correct;
}
}
public int ValueInteger
{
get
{
int valueInteger = 0;
if (Text != "")
{
try
{
valueInteger = Convert.ToInt32(Text);
}
catch { }
}
return valueInteger;
}
set
{
if (value == 0)
{
Text = "";
}
else
{
Text = value.ToString();
}
}
}
public bool ValueIntegerCorrect
{
get
{
bool correct = false;
try
{
int temp = Convert.ToInt32(Text); ;
correct = true;
}
catch { }
return correct;
}
}
public static decimal ConvertToDecimal(string stringToConvert)
{
if (stringToConvert == "") { stringToConvert = "0"; }
// заменяем разделитель с дробной частью, он может быть точкой или запятой и различаться для значения из базы и текущего компьютера
string decimalSeparator = System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator;
stringToConvert = System.Text.RegularExpressions.Regex.Replace(stringToConvert.Trim(), @"\,|\.", decimalSeparator);
decimal result = Decimal.Parse(stringToConvert, System.Globalization.NumberStyles.Any, System.Threading.Thread.CurrentThread.CurrentCulture);
return result;
}
// end public partial class TextBoxPlus : TextBox
}
Jag har också följt fallet så länge jag kan minnas. Sedan jag läste om det i paeanrstidpingpr och sedan hemsidan som nu blivit till blogg. Hoppas hoppas hoppas, seminariet mynnar ut i något konkret. Värsta mardrömmen säger vissa är att barnen dör/mördas, men jag skulle nog säga att det är om de försvinner och man får inget veta. Varken när/hur/var.