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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> AutoSize только по одной оси, label, textBox.... 
V
    Опции темы
Atomic
Дата 20.12.2006, 21:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 23
Регистрация: 4.12.2006

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



Нужно, задав жестко полю с текстом (label, textbox или др.) ширину, сделать автоподстройку высоты поля так, чтобы весь текст (мультилайн) был виден без скроллинга.
Из близкого нашел в label свойство AutoSize, но оно работает сразу по обоим осям, что не подходит. 
Может, кто-нибудь знает, как получить желаемое?
PM   Вверх
Dmitriy_Donetsk
Дата 21.12.2006, 00:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 28.9.2006

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



Возможно решение, которое я предложу не самое оптимальное, но тем 
не менее работает.
Итак, создаем textBox1, устанавливаем Width, который не будет меняться,
далее в зависимости от количества строк в textBox1 (multiline) устанавливаем
высоту (Height):


Код

 private void Form1_Load(object sender, EventArgs e)
        {
            string[] tempArray = new string[textBox1.Lines.Length];
            tempArray = textBox1.Lines;
            //в tempArray.Length - Количество строк в textBox1 

            textBox1.Height = tempArray.Length*14;  
            // 14 - число пикселей для 1 строки,будет 1 лишняя пустая строка,
           // в принципе не страшно, если взять 13, то последнюю строку обрежит -> ставь 14 
        }

PM MAIL   Вверх
Atomic
Дата 21.12.2006, 10:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 23
Регистрация: 4.12.2006

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



В этом решении есть много минусов, но другого и я не вижу.
Только одно но - при уменьшении TextBoxа меньше ширины строки, он переносит текст на следующую. Таким образом количество строк становится неопределенным. Известно только, что их не меньше textBox1.Lines.Length.
После доработки, у меня получился такой вариант:
Код

private void panel2_Resize(object sender, EventArgs e)
{
    textBox1.Width = panel2.Width;//Это я так ширину устанавливаю.
    // А теперь подсчитам, сколько строк у нас реально получается
    int n = 1;// это - кол-во строк. 1 строка есть всегда.
    int k = 0;// а это вспомогательная переменная - кол-во букв в строке
    for (int i = 0; i < textBox1.Text.Length; i++ ) 
        switch (textBox1.Text[i])
        {
            case '\n': n++; k = 0; break;// перенос строки - увеличиваем кол-во строк на 1
            case '\r': break;// второй символ переноса строки - нам и одного хватит. Но убрать его нужно, иначе он будет портить подсчет.
            default: 
                k++;
                if (k * 6 >= this.panel2.Width-6 ) { k = 0; n++; }// если ширина строки достигла максимально допустимой, 
                                                                             // то увеличиваем счетчик строк.
                // здесь k*6 - длинна полученной строки, а вторая 6 - это textbox1.margin.left+...rigth. 
                // Здесь нужно как-то иначе получить ширину символа.
                break;
        }

    textBox1.Height = n * 18;// '14' мне оказалось мало - при уменьшении textBoxа до ~5 символов терялось несколько строк. 
                                 // С '18' строки не теряются, при крайних значениях ширины высота получается очень точно,
                                 // но при средних значениях добавляется несколько лишних строк. Но это не так смертельно.
                                 // А вообще, нужно от куда-то брать эту константу (как и ширину символов), а не подбирать.
}


Но мне почему-то не очень нравится такое решение. Хотелось бы автоматизации.
PM   Вверх
Naum
Дата 21.12.2006, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 743
Регистрация: 7.9.2005
Где: Саратов, ул. Поса дского, 298

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



Dmitriy_Donetsk

зачем string tempArray, если нужно только количество строк?
Цитата(Dmitriy_Donetsk @  21.12.2006,  01:40 Найти цитируемый пост)
// 14 - число пикселей для 1 строки,будет 1 лишняя пустая строка,
           // в принципе не страшно, если взять 13, то последнюю строку обрежит -> ставь 14 

А если шрифт другой.
Код

using (Graphics g=this.CreateGraphics())
{
   textBox1.Height=textBox1.Lines.Length*g.MeasureString("M",textBox1.Font).Height;
}

А лучше добавить в класс формы поле (например, textHeight) и в событиях Form1_Load и textBox1_FontChanged пересчитывать его. А затем вместо g.MeasureString....... написать textHeight.


--------------------
У нас всего два праздника Новый год и ТЯПница.
PM MAIL ICQ   Вверх
Naum
Дата 21.12.2006, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 743
Регистрация: 7.9.2005
Где: Саратов, ул. Поса дского, 298

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



А можно еще проще
Код

using (Grapgics g=this.CreateGraphics())
{
   textBox1.Heigth=Convert.ToInt32(g.MeasureString(textBox1.Text.TrimEnd(" ".ToCharArray),texBox1.Font).Height);
}


Добавлено @ 11:37 
Можное еще добавить "технологический зазор" +2.

Это сообщение отредактировал(а) Naum - 21.12.2006, 11:49


--------------------
У нас всего два праздника Новый год и ТЯПница.
PM MAIL ICQ   Вверх
DarkDragon
Дата 21.12.2006, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GradVin
**


Профиль
Группа: Участник
Сообщений: 296
Регистрация: 19.8.2006

Репутация: 3
Всего: 8



Naum, а у меня еще один вариант:
Код

textBox1.Height = textBox1.Lines.Length * textBox1.Font.Height;

 smile 


PM MAIL   Вверх
DarkDragon
Дата 21.12.2006, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GradVin
**


Профиль
Группа: Участник
Сообщений: 296
Регистрация: 19.8.2006

Репутация: 3
Всего: 8



Цитата(Naum @  21.12.2006,  11:35 Найти цитируемый пост)
А можно еще проще

или еще, еще проще   smile 
Код

        private void AutoHeight(Control ctrl)
        {
            using (Graphics g = ctrl.CreateGraphics())
            {
                ctrl.Height = Convert.ToInt32(g.MeasureString(ctrl.Text, ctrl.Font,ctrl.Width).Height) + ctrl.Font.Height;
            }
        }

AutoHeight (label1);

PM MAIL   Вверх
Atomic
Дата 22.12.2006, 00:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 23
Регистрация: 4.12.2006

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



textBox1.Font.Height - это хорошо. Нужно где нибудь записать на салфетке.
А Convert.ToInt32(g.MeasureString(ctrl.Text, ctrl.Font,ctrl.Width).Height даже лучше, потому, что там есть .Width.
Но заметил еще одну гадость - этот нехороший textBox переносит по словам. Соответственно, алгоритм подсчета строк должен быть довольно сложным. Или давать строки с запасом.
PM   Вверх
Naum
Дата 22.12.2006, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 743
Регистрация: 7.9.2005
Где: Саратов, ул. Поса дского, 298

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



Цитата(Atomic @  22.12.2006,  01:53 Найти цитируемый пост)
Convert.ToInt32(g.MeasureString(ctrl.Text, ctrl.Font,ctrl.Width).Height даже лучше

Может быть, но считаться быстрее будет конечно textBox1.Font.Heigt.



--------------------
У нас всего два праздника Новый год и ТЯПница.
PM MAIL ICQ   Вверх
DarkDragon
Дата 22.12.2006, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


GradVin
**


Профиль
Группа: Участник
Сообщений: 296
Регистрация: 19.8.2006

Репутация: 3
Всего: 8



Цитата(Atomic @  22.12.2006,  00:53 Найти цитируемый пост)
Но заметил еще одну гадость - этот нехороший textBox переносит по словам. Соответственно, алгоритм подсчета строк должен быть довольно сложным. Или давать строки с запасом. 

Ф-ция MeasureString - учитывает и WordWrap (перенос слов), но можно его отключить используя StringFormat, устанавливая флаг на NoWrap, но здесь это не нужно. Впринцепе можно пользоваться AutoHeight и на label, textbox и т. д..
PM MAIL   Вверх
Atomic
Дата 24.12.2006, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 23
Регистрация: 4.12.2006

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



Цитата(DarkDragon @  22.12.2006,  15:21 Найти цитируемый пост)
Впринцепе можно пользоваться AutoHeight и на label, textbox и т. д.. 

Да, действительно. И как раз то, что и требовалось. 
PM   Вверх
yury_sh
Дата 29.1.2007, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 29.1.2007

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



К сожалению метод с MeasureString иногда врет. Не знаю, в чем дело - то ли фонт чуть-чуть не тот, то ли лейбл рисует текст чуть иначе чем функция MeasureString. Кроме того, чтобы его правильно реализовать, нужно учитывать рамку и ...Padding (?). И вообще, он зависит от имплементации лейбла - кто его знает с каким отступом, межстрочным интервалом и т.п. лейбл рисует текст.

Но есть способ еще красивее. Во всяком случае для лейбла работает как из пушки.

Код

int AutoHeight(Label lbl)
{
  lbl.Text = s;
  Size sz = lblHelp.GetPreferredSize(lbl.Size);
  return lblHelp.Height = sz.Height;
}


Документация по GetPreferredSize явно не говорит об этом, но экспериментально выходит, что функция всегда возвращает ширину <= переданной, и высоту необходимую при этой ширине.


Это сообщение отредактировал(а) yury_sh - 29.1.2007, 15:29
PM MAIL   Вверх
Naum
Дата 29.1.2007, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 743
Регистрация: 7.9.2005
Где: Саратов, ул. Поса дского, 298

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



yury_sh, имхо, заслуженный +1.


--------------------
У нас всего два праздника Новый год и ТЯПница.
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

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


 




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


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

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