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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Разноцветный текст в DataGridView 
:(
    Опции темы
Unsane
Дата 16.2.2008, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Необходимо было реализовать раскраску текста. Цвет определяется по "спецсимволу"(^+число от 0 до 9).
Собственно раскраску реализовал, но есть баги, которые исправить не могу:
1. Неправильно считается ширина выводимого текста, всвязи с чем между 2 частями разного цвета образуется пробел. Например, "Ninzia^1DDT" отображается так user posted image, а должно быть NinziaDDT.
2. Иногда при перерисовке выскакивает ошибка в 6 строке(код ниже) "Attempted to read or write protected memory. 
This is often an indication that other memory is corrupt."

Код

        private void DGV_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {

            if (e.RowIndex >= 0 && e.ColumnIndex == 1)
            {
                e.PaintBackground(e.CellBounds, true);
                Settings lSettings = new Settings();
                if (lSettings.GetItemPropertyValue("Programm/Colorize", "NickName", false))
                {
                    if (e.Value != null)
                    {
                        string[] tmp;
                        string wrk = String.Empty;
                        Brush clr = Brushes.White;
                        int bx = e.CellBounds.X + 2;
                        int by = e.CellBounds.Y + 4;
                        tmp = e.Value.ToString().Split('^');
                        for (int i = 0; i < tmp.Length; i++)
                        {
                            if (tmp[i].Length > 0 && tmp.Length > 0)
                            {
                                switch (tmp[i].Substring(0, 1))
                                {
                                    case "0":
                                        clr = Brushes.Black;
                                        e.Graphics.DrawString(tmp[i].Substring(1), e.CellStyle.Font, clr, bx + e.Graphics.MeasureString(wrk, e.CellStyle.Font).Width, by);
                                        wrk += tmp[i].Substring(1);
                                        break;
                                    case "1":
                                        clr = Brushes.Red;
                                        e.Graphics.DrawString(tmp[i].Substring(1), e.CellStyle.Font, clr, bx + e.Graphics.MeasureString(wrk, e.CellStyle.Font).Width, by);
                                        wrk += tmp[i].Substring(1);
                                        break;
                                    case "2":
                                        clr = Brushes.Green;
                                        e.Graphics.DrawString(tmp[i].Substring(1), e.CellStyle.Font, clr, bx + e.Graphics.MeasureString(wrk, e.CellStyle.Font).Width, by);
                                        wrk += tmp[i].Substring(1);
                                        break;
                                    case "3":
                                        clr = Brushes.Yellow;
                                        e.Graphics.DrawString(tmp[i].Substring(1), e.CellStyle.Font, clr, bx + e.Graphics.MeasureString(wrk, e.CellStyle.Font).Width, by);
                                        wrk += tmp[i].Substring(1);
                                        break;
                                    case "4":
                                        clr = Brushes.Blue;
                                        e.Graphics.DrawString(tmp[i].Substring(1), e.CellStyle.Font, clr, bx + e.Graphics.MeasureString(wrk, e.CellStyle.Font).Width, by);
                                        wrk += tmp[i].Substring(1);
                                        break;
                                    case "5":
                                        clr = Brushes.LightSeaGreen;
                                        e.Graphics.DrawString(tmp[i].Substring(1), e.CellStyle.Font, clr, bx + e.Graphics.MeasureString(wrk, e.CellStyle.Font).Width, by);
                                        wrk += tmp[i].Substring(1);
                                        break;
                                    case "6":
                                        clr = Brushes.Magenta;
                                        e.Graphics.DrawString(tmp[i].Substring(1), e.CellStyle.Font, clr, bx + e.Graphics.MeasureString(wrk, e.CellStyle.Font).Width, by);
                                        wrk += tmp[i].Substring(1);
                                        break;
                                    case "7":
                                        clr = Brushes.White;
                                        e.Graphics.DrawString(tmp[i].Substring(1), e.CellStyle.Font, clr, bx + e.Graphics.MeasureString(wrk, e.CellStyle.Font).Width, by);
                                        wrk += tmp[i].Substring(1);
                                        break;
                                    case "8":
                                        clr = Brushes.Peru;
                                        e.Graphics.DrawString(tmp[i].Substring(1), e.CellStyle.Font, clr, bx + e.Graphics.MeasureString(wrk, e.CellStyle.Font).Width, by);
                                        wrk += tmp[i].Substring(1);
                                        break;
                                    case "9":
                                        clr = Brushes.LightGray;
                                        e.Graphics.DrawString(tmp[i].Substring(1), e.CellStyle.Font, clr, bx + e.Graphics.MeasureString(wrk, e.CellStyle.Font).Width, by);
                                        wrk += tmp[i].Substring(1);
                                        break;
                                    default:
                                        e.Graphics.DrawString(tmp[i], e.CellStyle.Font, clr, bx + e.Graphics.MeasureString(wrk, e.CellStyle.Font).Width, by);
                                        wrk += tmp[i];
                                        break;
                                }
                            }
                        }
                        e.Handled = true;
                    }
                }
                else
                {
                    DGV_MembersList.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = Uncolor(e.Value.ToString());
                }
            }
        }


И еще хотелось бы узнить - можно ли рисовать текст с тенью, а то белый на бежевоп не легко разглядывать(user posted image).

Это сообщение отредактировал(а) Unsane - 16.2.2008, 12:24
--------------------
Я дурак.. Этим и интересен!
PM MAIL   Вверх
Ctrl
Дата 16.2.2008, 15:34 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



1. Почему пробелы: когда строка рисуется целиком, отдельные буквы могут немного перекрывать друг друга (например посмотри в экранную лупуна слог "Та"). Соответственно когда ты рисуешь строку частяями надо это учитывать(см. пример - там используется самый простой метод это расчитать)
2. Для отрисовки теней рисуй строку два раза со смещением(см. пример)

Ну а вот и сам пример отрисовки с правильным расчетом размера текста и тенями:
Код

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

namespace TestGridPaint {
    public partial class Form1 : Form {
        Brush defaultBrush = Brushes.Black;
        Brush[] brushes = new Brush[] { Brushes.Red, Brushes.Green, Brushes.Blue, Brushes.Magenta, Brushes.Yellow, Brushes.Aqua };
        List<TestGridRow> list = new List<TestGridRow>();
        public Form1() {
            InitializeComponent();
            InitData();
        }
        protected void InitData() {
            list.Add(new TestGridRow("test^0Test"));
            list.Add(new TestGridRow("test^1Test^2Test"));
            list.Add(new TestGridRow("test^2Test"));
            list.Add(new TestGridRow("test^3Test"));
            list.Add(new TestGridRow("test^3Test^1Test^5Test"));
            list.Add(new TestGridRow("test^4Test"));
            list.Add(new TestGridRow("test^5Test"));
            list.Add(new TestGridRow("testTest^"));
            dataGridView1.DataSource = new BindingSource(list, null);
        }
        protected void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) {
            if (e.Value == null || e.ColumnIndex != 0 || e.RowIndex == -1) return;
            e.PaintBackground(e.CellBounds, true);
            List<TextElement> textElements = CollectTextElements("^", (string)e.Value, defaultBrush, brushes);
            if (textElements.Count > 0) {
                PointF textLocation = new PointF((float)e.CellBounds.Left, (float)e.CellBounds.Top) + new SizeF(0, 4);
                DrawCompositeText(e.Graphics, e.CellStyle.Font, textLocation, textElements, true);
            }
            else e.PaintContent(e.CellBounds);
            e.Handled = true;
        }
        protected void DrawCompositeText(Graphics g, Font font, PointF startPoint, List<TextElement> textElements , bool shadowed) {
            float widthCorrection = CalcCompositeTextWidthCorrection(g, font, textElements);
            foreach (TextElement ct in textElements) {
                SizeF textSize = g.MeasureString(ct.Text, font);
                if (shadowed) g.DrawString(ct.Text, font, Brushes.DarkGray, new RectangleF(startPoint+new SizeF(1.0f,1.0f), textSize));
                g.DrawString(ct.Text, font, ct.Brush, new RectangleF(startPoint, textSize));
                startPoint += new SizeF(textSize.Width - widthCorrection, 0);
            }
        }
        protected float CalcCompositeTextWidthCorrection(Graphics g, Font font, List<TextElement> textElements) {
            string solidText = string.Empty;
            SizeF compositeTextSize = SizeF.Empty;
            foreach (TextElement ct in textElements) {
                compositeTextSize += g.MeasureString(ct.Text, font);
                solidText += ct.Text;
            }
            SizeF solidTextSize = g.MeasureString(solidText, font);
            return (compositeTextSize.Width - solidTextSize.Width) / (textElements.Count - 1);
        }
        protected List<TextElement> CollectTextElements(string colorMarker, string cellText, Brush defaultBrush, Brush[] brushes) {
            List<TextElement> textElements = new List<TextElement>();
            int firstColorMarkerPos = cellText.IndexOf(colorMarker);
            if (firstColorMarkerPos != -1 && (firstColorMarkerPos + 1) != cellText.Length) {
                textElements.Add(new TextElement(defaultBrush, cellText.Substring(0, firstColorMarkerPos)));
                string parseTemplate = @"\" + colorMarker + @"((?<color>[0-9])(?<text>.*?\b))";
                MatchCollection matches = Regex.Matches(cellText, parseTemplate);
                foreach (Match m in matches) {
                    string color = (string)m.Groups["color"].Value;
                    string text = (string)m.Groups["text"].Value;
                    int colorIndex = Int32.Parse(color);
                    if (brushes.Length > colorIndex) textElements.Add(new TextElement(brushes[colorIndex], text));
                    else textElements.Add(new TextElement(defaultBrush, text));
                }
            }
            return textElements;
        }
        public struct TextElement {
            public TextElement(Brush c, string text) {
                Brush = c;
                Text = text;
            }
            public Brush Brush;
            public string Text;
        }
    }
    public class TestGridRow {
        string cellCore;
        public TestGridRow(string s) { this.cellCore = s; }
        public string Cell { get { return cellCore; } }
    }
}


Добавлено через 5 минут и 7 секунд
в примере, если внимательно посмотришь, приведен, наверное более правильный парсинг содержимого ячейки через регулярное выражение
PM MAIL ICQ   Вверх
Unsane
Дата 16.2.2008, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Спасибо большое, а то я весь мозг сломал! smile 

Это сообщение отредактировал(а) Unsane - 16.2.2008, 23:03
--------------------
Я дурак.. Этим и интересен!
PM MAIL   Вверх
Ctrl
Дата 17.2.2008, 21:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Хочу поправить:

Цитата

Unsane 17.2.2008, 19:28:
нашлась ошибка.
Если слово начинается с цветового маркера, то первsq блок попросту пропадает.
"^1-=AJAX=-^0Davids" рисуется как Davids черного цвета.


Ctrl 17.2.2008, 19:52:
Цитата

Ага ты прав... ошибка действительно присутствует, но только не из-за того, что строка начинается с маркера, а из-за символов "-" и "=" (если их убрать - то все работает).
Странно, конечно, вроже должно и с этими символами работать работать.... Сейчас немного поисследую и попробую обойти это ограничение....


Разобрался:
Строчка 
Код

string parseTemplate = @"\" + colorMarker + @"((?<color>[0-9])(?<text>.*?\b))";

Ошибка в использовании \b (просто конец слова, каким может являтьс тот же символ "-")
  - надо явно использовать либо признак цвета ("^0" и т.п.), либо конец текста

Фикс:
Код

string parseTemplate = @"\" + colorMarker + @"((?<color>[0-9])(?<text>.*?)(?=(\" + colorMarker + "[0-9]|$)))";


Unsane, спасибо за внимательность , удачи!
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




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


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

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