Создаем расширенный Control в WinForms наследуясь от существующего

Задача: немного изменить внешний вид и/или поведение существующего элемента управления 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
    }
 

Комментарии

Создаем расширенный Control в WinForms наследуясь от существующего — 1 комментарий

  1. 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.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *


*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>