Выделение текста цветом по клику мышью

17.08.2017

Зачастую, просматривая свои электронные отчеты, вам хочется выделить некоторые строки цветом, как вы бы сделали это с бумажным вариантом при помощи выделителя. Ну что же, это действительно возможно. В режиме предварительного просмотра отчета можно выделять нужные текстовые поля с помощью клика мыши. То есть, вы кликаете на текстовое поле и его цвет изменяется. При повторном нажатии выделение цветом исчезает. Я покажу вам два способа как это сделать, и оба они подразумевают использование скрипта отчета.

Способ 1. Суть этого способа заключается в использовании sender (объекта, который вызвал событие) для присвоения нового цвета в обработчике события OnCklick.  При этом, нужно обновить страницу отчета в кэше, т.к. режим предварительного просмотра отображает отчет из него.

Итак, создадим простейший отчет со списком товаров:

Допустим, мы хотим выделять цветом одно из полей при нажатии мышью. А также убирать выделение при повторном нажатии на него. Для текстового объекта, в котором выводится поле Products.ProductName, создаем событие Click.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 private void Text1_Click(object sender, EventArgs e)
 { 
 if (sender is TextObject)
 {
 //Определяем sender как TextObject
 TextObject obj = sender as TextObject;
 //Метод перекрашивания объекта цветом
 SwitchColor(obj);
 if(Report.Preview != null)
 {
 //Обновить текущую страницу отчета в кэше, если отчет просматривается на десктопе
 Report.PreparedPages.ModifyPage(Report.Preview.PageNo - 1, obj.Page as ReportPage);
 //Перерисовать превью
 Report.Preview.Refresh();
 } 
 } 
 }
 
 private void SwitchColor(TextObject obj)
 {
 //Проверяем имеет ли объект желтую заливку
 if (obj.Fill is SolidFill && (obj.Fill as SolidFill).Color != Color.Yellow)
 //Заливаем желтым
 obj.Fill = new SolidFill(Color.Yellow);
 //Очищаем заливку
 else
 obj.Fill = new SolidFill(Color.Transparent); 
 }
 

Как вы видим, из события нажатия мы берем объект sender, определяем его как текстовый объект и изменяем его заливку. Затем, перерисовываем страницу отчета в кэше.

В случае, если у нас веб отчет, мы просто изменяем заливку объекта, без перерисовывания страницы отчета.

Рассмотрим альтернативный способ.

Способ 2. Суть этого способа заключается в определении координат объекта, который мы будем заливать цветом. Затем мы обновляем страницу отчета в кэше, как и в первом способе.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private void Text1_Click(object sender, EventArgs e)
 { 
 if (sender is TextObject)
 {
 // Получаем номер текущей страницы
 int pageNo = Report.Preview.PageNo - 1;
 // Получаем саму страницу по номеру
 ReportPage page = Report.PreparedPages.GetPage(pageNo);
 // Определяем sender как TextObject – это фантомный объект, нам же нужен оригинальный объект из страницы предварительного просмотра
 TextObject obj = sender as TextObject;
 // Ищем оригинальный объект на странице предварительного просмотра
 foreach(ReportComponentBase b in page.AllObjects)
 // Нужно идентифицировать объект по имени и координатам
 if (b.Name == obj.Name && b.AbsTop == obj.AbsTop && b.AbsLeft == obj.AbsLeft)
 {
 // Получаем оригинальный объект
 obj = b as TextObject;
 break;
 } 
 // Задаем заливку объекта
 if (obj.Fill is SolidFill && (obj.Fill as SolidFill).Color != Color.Yellow)
 obj.Fill = new SolidFill(Color.Yellow);
 else
 obj.Fill = new SolidFill(Color.Transparent);
 
 // Обновляем страницу отчета в кэше
 Report.PreparedPages.ModifyPage(pageNo, page);
 // перерисовываем превью
 Report.Preview.Refresh();
 }
 }
 

Продемонстрируем работу этого кода:

Этот способ объективно сложнее, и работает только для режима предварительного просмотра. Однако, в нем есть свои преимущества. Допустим вы хотите выделить цветом не только текстовый объект, на который вы нажали, но и всю строку в таблице. Тогда добавляем еще один текстовый объект поверх того, на который мы будем кликать. Растягиваем его на всю ширину строки. Тут важно, чтобы левая граница добавляемого текстового объекта совпадала с левой границей текстового объекта, для которого мы создали событие Click. Делаем правый клик по нему. И выбираем из меню:

 

Тем самым передвигаем этот объект на задний план, чтобы он не перекрывал другие текстовые поля.

Модифицируем немного наш предыдущий код:

1
2
3
4
5
6
7
 if (b.AbsTop == obj.AbsTop && b.AbsLeft == obj.AbsLeft)
 {
 // Получаем оригинальный объект
 obj = b as TextObject;
 break;
 } 
 

Из условия я убрал сравнение по имени и оставил лишь сравнение по координатам начала поля.

А теперь запустим отчет и нажмем на название какого-нибудь продукта:

 

Таким образом, оба способа жизнеспособны. Первый – проще, но позволяет выделять только конкретный объект, который мы получаем в sender. Второй – сложнее, но позволяет выделять цветом не только объект из sender, но и другие. Нужно лишь указать их координаты. В веб отчете вы сможете использовать только первый способ.

Конечно же вы можете не только изменять цвет фона, но и цвет, стиль или шрифт самого текста. Кроме того, все подобные модификации отчета сохранятся при экспорте в любой из поддерживаемых форматов, например в PDF.

Надеюсь вам пригодятся этот небольшой лайфхак.

20 ноября 2024

Локализация и смена языков в FastReport VCL

FastReport VCL поддерживает 40 языков для локализации интерфейса и позволяет изменять язык на лету через меню или код, без перекомпиляции.
1 ноября 2024

Новые возможности редактора отчетов FastReport VCL

Рассматриваем новые возможности редактора отчетов: выносные линии, подсветка пересекающихся объектов, обновлённые деревья отчетов и данных.
30 октября 2024

Использование стилей при создании отчетов в FastReport VCL

В статье подробно рассматривается одна из новых возможностей FastReport VCL – применение стилей и страниц стилей.