Модераторы: gambit, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите с контролом 
V
    Опции темы
Ch0bits
  Дата 24.1.2006, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Python Dev.
****


Профиль
Группа: Завсегдатай
Сообщений: 2124
Регистрация: 21.2.2005
Где: Казань

Репутация: 1
Всего: 62



Решил написать контрол SpinEdit, который должен содержать число, ограниченное верхним и нижним пределом, а также умеет его изменять колёсиком мыши и кнопками вверх и вниз.
Не пойму почему такие глюки:
1. При установке значения Digit, оно всё равно сбрасывается на 0, хотя MaxDigit и MinDigit работают нормально.
2. Не перехватывается нажатие клавиши!
Код

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace LifeGame
{
    public partial class SpinEdit : UserControl
    {
        public SpinEdit()
        {
            InitializeComponent();
            textBox1.Text = Digit.ToString();
        }

        // Подгоняем размеры
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            this.Height = textBox1.Height;
        }

        // Значения по умолчанию
        public int digit;
        public int maxDigit;
        public int minDigit;

        // Пропертя содержащая текущее число
        public int Digit
        {
            get{  return digit; }
            set
            {
                // Проверка числа на выход за рамки
                if (value > maxDigit)
                {
                    digit = maxDigit;
                    textBox1.ForeColor = Color.Red; // Красным помечаем максимальное число
                }
                else
                    if (value < minDigit)
                    {
                        digit = minDigit;
                        textBox1.ForeColor = Color.Green; // Зелёным метим минимальное число
                    }
                    else
                    {
                        digit = value;
                        textBox1.ForeColor = Color.Black; // Остальные числа чёрного цвета
                    }
                textBox1.Text = digit.ToString();
            }
        }

        // Пропертя содержащая максимальное число
        public int MaxDigit
        {
            get{  return maxDigit; }
            set
            {
                if (value >= minDigit) maxDigit = value;
            }
        }

        // Пропертя содержащая минимальное число
        public int MinDigit
        {
            get { return minDigit; }
            set
            {
                if (value <= maxDigit) minDigit = value;
            }
        }

        // Изменяем число от движения колёсика мыши
        protected override void OnMouseWheel(MouseEventArgs e)
        {
            if (e.Delta > 0)
                Digit++;
            else
                Digit--;
        }

        // !!! ПОЧЕМУ НАЖАТИЕ НА КНОПКУ НЕ ПЕРЕХВАТЫВАЕТСЯ???
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            base.OnKeyPress(e);
            MessageBox.Show("КНОПКА ПЕРЕХВАЧЕНА");
        }
          
    }
}


Код

namespace LifeGame
{
    partial class SpinEdit
    {
        /// <summary> 
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary> 
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary> 
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // textBox1
            // 
            this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.textBox1.Location = new System.Drawing.Point(0, 0);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(138, 20);
            this.textBox1.TabIndex = 0;
            // 
            // SpinEdit
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.Controls.Add(this.textBox1);
            this.Name = "SpinEdit";
            this.Size = new System.Drawing.Size(138, 29);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.TextBox textBox1;


    }
}

smile
PM WWW   Вверх
Ch0bits
Дата 25.1.2006, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Python Dev.
****


Профиль
Группа: Завсегдатай
Сообщений: 2124
Регистрация: 21.2.2005
Где: Казань

Репутация: 1
Всего: 62



Код

using System;
using System.Drawing;
using System.Windows.Forms;

namespace LifeGame
{
    public partial class SpinEdit : UserControl
    {
        public SpinEdit()
        {
            InitializeComponent();
            textBox1.Text = Digit.ToString();
            // Устанавливаем эвенты
            this.textBox1.TextChanged += new System.EventHandler(this.OnTextChanged);
            this.textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnKeyDown);
        }

        // Подгоняем размеры
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            this.Height = textBox1.Height;
        }

        private int digit;
        private int maxDigit;
        private int minDigit;

        // Пропертя содержащая текущее число
        public int Digit
        {
            get{  return digit; }
            set
            {
                // Проверка числа на выход за рамки
                if (value >= maxDigit)
                {
                    digit = maxDigit;
                    textBox1.ForeColor = Color.Red; // Красным помечаем максимальное число
                }
                else
                    if (value <= minDigit)
                    {
                        digit = minDigit;
                        textBox1.ForeColor = Color.Green; // Зелёным метим минимальное число
                    }
                    else
                    {
                        digit = value;
                        textBox1.ForeColor = Color.Black; // Остальные числа чёрного цвета
                    }
                textBox1.Text = digit.ToString();
            }
        }

        // Пропертя содержащая максимальное число
        public int MaxDigit
        {
            get{  return maxDigit; }
            set
            {
                if (value >= minDigit) maxDigit = value;
            }
        }

        // Пропертя содержащая минимальное число
        public int MinDigit
        {
            get { return minDigit; }
            set
            {
                if (value <= maxDigit) minDigit = value;
            }
        }

        // Изменяем число от движения колёсика мыши
        protected override void OnMouseWheel(MouseEventArgs e)
        {
            if (e.Delta > 0)
                Digit++;
            else
                Digit--;
        }

        // Фильтрация вводимых с клавиатуры клавиш
        private void OnKeyDown(object sender, KeyEventArgs e)
        {
            e.SuppressKeyPress = true; 
            // Пропускаем цифровые кнопки с основной клавиатуры
            if ((e.KeyCode >= Keys.D0) && (e.KeyCode <= Keys.D9)) e.SuppressKeyPress = false;
            // Пропускаем цифровые кнопки с NumPad'а
            if ((e.KeyCode >= Keys.NumPad0) && (e.KeyCode <= Keys.NumPad9)) e.SuppressKeyPress = false;
            // Пропускаем Delete, Back, Left и Right
            if ((e.KeyCode == Keys.Delete) || (e.KeyCode == Keys.Back) ||
                (e.KeyCode == Keys.Left) || (e.KeyCode == Keys.Right)) e.SuppressKeyPress = false;
        }

        // При изменении текста пользователем меняем Digit
        private void OnTextChanged(object sender, EventArgs e)
        {
            if (textBox1.Text == "") textBox1.Text = "0"; // Если стёрли все цифры сразу
            Digit = int.Parse(textBox1.Text); 
        }
          
    }
}


Теперь осталась только первая ошибка.

Да! Да! Я знаю какой я ламер! smile Но может всё таки кто-нибудь поможет?

Это сообщение отредактировал(а) Ch0bits - 25.1.2006, 12:25
PM WWW   Вверх
mr.DUDA
Дата 25.1.2006, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 24
Всего: 232



Похоже на рекурсию: при изменении текста срабатывает OnTextChanged, в котором присваивается значение свойству Digit; в set-е этого свойства устанавливается новое значение у textBox1.Text, что опять приводит к вызову OnTextChanged - и так далее по кругу, до переполнения стека... Проверь, не валится ли какое-нибудь исключение в отладке.


--------------------
user posted image
PM MAIL WWW   Вверх
Ch0bits
Дата 25.1.2006, 22:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Python Dev.
****


Профиль
Группа: Завсегдатай
Сообщений: 2124
Регистрация: 21.2.2005
Где: Казань

Репутация: 1
Всего: 62



mr.DUDA
Если бы была рекурсия, то GUI бы заметно подвисал и загрузке проца, но такого не происходит.
Под отладкой: OnTextChange срабатывает только если текст изменился, т.е. если текст меняется на тот же самый OnTextChange не срабатывает.
PM WWW   Вверх
mr.DUDA
Дата 26.1.2006, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 24
Всего: 232



Во-первых, все свойства, которые видны в дизайнере, должны проверять режим, в котором находится контрол: в DesignMode или нет. Иначе будут непонятные глюки при работе в дизайн-тайме smile

Во-вторых, текст в текстбоксе вначале всегда "0", даже если поставить в дизайнере Digit в другое значение. Это просходит потому, что порядок инициализации компонентов следующий:

1) InitializeComponent() у SpinEdit, с установкой дефолтных значений MinDigit = MaxDigit = Digit = 0
2) InitializeComponent() у формы, присвоение свойств spinEdit1:

Код

            this.spinEdit1.Digit = 4;
            this.spinEdit1.Location = new System.Drawing.Point(57, 36);
            this.spinEdit1.MaxDigit = 10;
            this.spinEdit1.MinDigit = 1;


Как видно, сначала присваивается Digit, и срабатывает ограничение на макс. значение, т.к. MaxDigit всё ещё не проинициализирован и равен 0. В итоге имеем Digit=0. Чтобы этого не происходило, можно поддержать в своём контроле интерфейс ISupportInitialize, и в методах BeginInit / EndInit устанавливать и сбрасывать некий флаг, который использовать вместе с DesignMode. При добавлении SpinEdit на форму, в коде InitializeComponent формы будут автоматически добавлены вызовы BeginInit вначале и EndInit в конце. Вот код, который получился в результате:

Код
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public partial class SpinEdit : UserControl, ISupportInitialize
    {
        public SpinEdit()
        {
            InitializeComponent();
            textBox1.Text = Digit.ToString();
            // Устанавливаем эвенты
            this.textBox1.TextChanged += new System.EventHandler(this.OnTextChanged);
            this.textBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnKeyDown);
        }

        // Подгоняем размеры
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            this.Height = textBox1.Height;
        }

        private int digit;
        private int maxDigit;
        private int minDigit;

        // Пропертя содержащая максимальное число
        public int MaxDigit
        {
            get { return maxDigit; }
            set
            {
                if (this.DesignMode || isInitNow)
                    this.maxDigit = value;
                else
                {
                    if (value >= minDigit) maxDigit = value;
                }
            }
        }

        // Пропертя содержащая минимальное число
        public int MinDigit
        {
            get { return minDigit; }
            set
            {
                if (this.DesignMode || isInitNow)
                    minDigit = value;
                else
                {
                    if (value <= maxDigit) minDigit = value;
                }
            }
        }

        // Пропертя содержащая текущее число
        public int Digit
        {
            get { return digit; }
            set
            {
                if (this.DesignMode || isInitNow)
                {
                    this.digit = value;
                    this.textBox1.Text = value.ToString();
                }
                else
                {
                    // Проверка числа на выход за рамки
                    if (value >= maxDigit)
                    {
                        digit = maxDigit;
                        textBox1.ForeColor = Color.Red; // Красным помечаем максимальное число
                    }
                    else
                    {
                        if (value <= minDigit)
                        {
                            digit = minDigit;
                            textBox1.ForeColor = Color.Green; // Зелёным метим минимальное число
                        }
                        else
                        {
                            digit = value;
                            textBox1.ForeColor = Color.Black; // Остальные числа чёрного цвета
                        }
                    }
                    textBox1.Text = digit.ToString();
                }
            }
        }


        // Изменяем число от движения колёсика мыши
        protected override void OnMouseWheel(MouseEventArgs e)
        {
            if (e.Delta > 0)
                Digit++;
            else
                Digit--;
        }

        // Фильтрация вводимых с клавиатуры клавиш
        private void OnKeyDown(object sender, KeyEventArgs e)
        {
            e.SuppressKeyPress = true;
            // Пропускаем цифровые кнопки с основной клавиатуры
            if ((e.KeyCode >= Keys.D0) && (e.KeyCode <= Keys.D9)) e.SuppressKeyPress = false;
            // Пропускаем цифровые кнопки с NumPad'а
            if ((e.KeyCode >= Keys.NumPad0) && (e.KeyCode <= Keys.NumPad9)) e.SuppressKeyPress = false;
            // Пропускаем Delete, Back, Left и Right
            if ((e.KeyCode == Keys.Delete) || (e.KeyCode == Keys.Back) ||
            (e.KeyCode == Keys.Left) || (e.KeyCode == Keys.Right)) e.SuppressKeyPress = false;
        }

        // При изменении текста пользователем меняем Digit
        private void OnTextChanged(object sender, EventArgs e)
        {
            if (textBox1.Text == "") textBox1.Text = "0"; // Если стёрли все цифры сразу
            Digit = int.Parse(textBox1.Text);
        }

        #region ISupportInitialize Members

        bool isInitNow = false;

        public void BeginInit()
        {
            isInitNow = true;
        }

        public void EndInit()
        {
            isInitNow = false;
        }

        #endregion
    }
}



--------------------
user posted image
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Разработка Windows Forms | Следующая тема »


 




[ Время генерации скрипта: 0.0594 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.