ComboBox - подстраиваем ширину выпадающего списка под самый длинный элемент

Два очевидных решения - сделать всплывающую подсказку или увеличить ширину самого выпадающего списка. Вычисляем максимальную длину строки в таблице-справочнике:

// устанавливаем ширину выпадающего списка на основании наибольшей длины элемента в списке
var graphics = CreateGraphics();

comboBoxColumn.DropDownWidth = (from width in (from DataRow item in someDataSet.someDataTable.Rows  select Convert.ToInt32(graphics.MeasureString(item["TEXT_SOMETH"].ToString(), Font).Width)) select width).Max();

Setting DropDown list width of DataGridView ComboBoxColumn - WinForms

Рубрика: WinForms | Добавить комментарий

Работа с Excel из C# через COM Interop

Задача: вывести данные в таблицу Excel с красивым оформлением и открыть ее, чтобы пользователь мог напечатать или сохранить средствами самого Excel. Необходимо поддерживать все версии Office, начиная с 97, то есть вывод в новые xml-форматы Office 2007 и выше невозможен

Самая сложная часть - работа с оформлением, так как во-первых интерфейс Excel крайне неочевиден, запутан и плохо документирован, во-вторых оформление Excel таблицы из кода работает достаточно медленно. В связи с этим в большинстве случаев подойдет вариант с использованием шаблонов .xlt. Так как мы выводим файл для просмотра и печати, без расчета на сложные вычисления, диаграммы и прочие прелести жизни, мы можем привести формат всех ячеек к тексту и забыть про различные типы данных.
Читать далее

Рубрика: C# | Добавить комментарий

Как создать DataTable программно

Задача: создать DataTable внутри кода C#. На самом деле все делается очень просто, по официальной документации на msdn, так что здесь будет в прямом смысле слова краткая заметка на память - просто, коротко и удобно, большая часть параметров остается со значениями по умолчанию.

DataTable someTable = new DataTable();
DataColumn column;

column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "INT_ID_COLUMN";
someTable.Columns.Add(column);

column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "STRING_COLUMN";
someTable.Columns.Add(column);

column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "STRING_COLUMN2";
someTable.Columns.Add(column);

DataRow rowToAdd = someTable.NewRow();
rowToAdd["INT_ID_COLUMN"] = 1;
rowToAdd["STRING_COLUMN"] = "Истинное одиночество — это присутствие человека, который тебя не понимает.";
rowToAdd["STRING_COLUMN2"] = "Элберт Хаббард";
someTable.Rows.Add(rowToAdd);
// вариант со вставкой строки на конкретную позицию
//someTable.Rows.InsertAt(rowToAdd, 0);
Рубрика: C# | Добавить комментарий

Нестандартная сортировка в DataGridView

Задача: изменить порядок сортировки значений в DataGridView по одному столбцу. Чаще всего стандартную сортировку приходится переделывать в случае наличия столбца со смешанными, текстово-числовыми данными или, проще говоря, строками, внутри которых содержатся числа вперемешку с текстом. Стандартная сортировка обрабатывает их как строки, сортируя по алфавиту - а нам нужно чтобы "значение 6" шло раньше "значения 10" или "значение-3-12" шло раньше "значение-1-11".

При выборке данных с сервера чаще всего создается отдельный столбец с нужным числовым значение и сортировка производится по нему.

Но в данному случае нам надо применить собственную сортировку только при клике по одной из колонок DataGridView, не перегружая данные и по минимуму изменяя остальной код. Самый простой способ:

1) Выключить стандартную сортировку для конкретной колонки через свойство DataGridViewColumn.SortMode

2) Добавить в служащую источником данных DataTable нужные для правильной сортировки колонки

3) Перехватить событие DataGridView.ColumnHeaderMouseClick и при клике по заголовку нужного столбца (определенного по свойству DataGridViewCellMouseEventArgs.ColumnIndex) вручную прописать свойство DataView.Sort нашего источника данных.

Рубрика: WinForms | Добавить комментарий

Как переместить элемент управления в WinForms

Задача: изменить местоположение элемента управления, например метки, в процессе работы программы. Положение определяется двумя координатами X и Y, которые отсчитываются от левого верхнего угла контейнера, в котором находится элемент - это может быть сама форма или контейнер внутри нее вроде GroupBox.

Изменить их напрямую мы не можем - местоположение элемента хранится в экземпляре класса Point, при обращении к свойству Location выдается его копия. Таким образом нам надо создать новый экземпляр класса Point и записать его в свойство Location.

someCoolLabel.Location = new Point(someCoolLabel.Location.X, 34);
Рубрика: WinForms | Добавить комментарий

Особенности работы с DataView, RowFilter и datetime

Задача: отфильтровать данные, загруженные из базы в DataTable (DataSet) и DataGridView без повторного обращения к БД. В C# и WinForms для этого можно использовать свойство RowFilter классов BindingSource.Filter и DataView.RowFilter . На самом деле BindingSource просто передает условие фильтрации в DataView или DataTable (в последнем случае условия от разных BindingSource будут перезаписываться), так что первично свойство RowFilter, в которое пишется текстовое условие с очень напоминающим Sql синтаксисом.

Синтаксис RowFilter совпадает с синтаксисом свойства DataColumn.Expression, документацию к которому и надо использовать недоумевающему программисту. Тем не менее в работе этого свойства хватает подводных камней и неочевидных моментов:

1. Условие от и до, ключевое слово BETWEEN - банально не работает. Вместо него надо использовать комбинацию более простых выражений, например

  someDataView.RowFilter = "ID >= 10 AND ID <= 60" 

Читать далее

Рубрика: C# | Добавить комментарий

Как изменить максимальный размер загружаемого файла в php

Для всех php приложений максимальный размер загружаемого файла задается в одном и не самом очевидном месте - не только для собственных, но и например для phphMyAdmin. По умолчанию он очень часто совсем маленький - особенно это озадачивает в спецпакетах для разработки сайтов на собственном компе вроде Denwer. Хочешь втянуть к себе базу данных из резервной копии - а оно не принимает файлы больше двух мегабайт. И что делать?

Ответ невероятно прост - надо редактировать файл php.ini - в котором собраны все настройки этого языка. Расположен этот замечательный файл где-то в районе usr\local\php5 (для денвера) или в похожем месте - зависит от хостинга или настроек вашего сервера. Это может быть \php-bin\ для моего нынешнего хостинга reg.ru или что-то в этом духе. Не все дешевые хостинги позволяют редактировать этот файл - но для простых сайтов обычно хватает настроек по умолчанию.
Читать далее

Рубрика: Без рубрики | Добавить комментарий

Ошибка http при загрузке файла в WordPress (php через fastcgi)

На самом деле это глубокая и глобальная ошибка, которая может быть вызвана массой разных причин (на форумах WordPress чего только не пробовали). Сейчас я рассмотрю только одну из них. При загрузке файла с помощью flash выдается сообщение о "Ошибке http", при использования более простого загрузчика еще более пугающая надпись

Internal Server Error. The server encountered an internal error or misconfiguration and was unable to complete your request.
(...)
More information about this error may be available in the server error log.

Ошибка происходит на уровне веб-сервера и в это сообщение уже наталкивает на верный путь - посмотреть журнал ошибок. Как его искать - вопрос к вашему хостеру, зависит от сервера. Будучи админом с нулевым опытом я его нашел простым просмотром каталогов. В журнале есть следующая запись:

mod_fcgid: HTTP request length 136127 (so far) exceeds MaxRequestLen (131072)

Иначе говоря, в настройка сервера, даже не php, указана очень маленький предельный размер загружаемого файла, точнее говоря не файла, а запроса к серверу.

Для исправления проблемы надо изменить этот параметр в конфигурационном файле apache - httpd.conf, добавив следующую строчку:

FcgidMaxRequestLen 15000000

Число означает максимальный размер в байтах, если мы хотим точно 15 мегабайт, можно поставить 15728640. Не стоит забывать, что размер загружаемого файла отельно настраивается для php, по умолчанию он обычно ограничен 2 мегабайтами.

Рубрика: Wordpress | Добавить комментарий

WordPress - слишком большой размер базы данных и ревизии записей

При переносе сайта на другой сервер столкнулся с неожиданной проблемой - очень большим размером базы, из-за которого PhpMyAdmin не мог ее нормально экспортировать/импортировать. При все при этом сайты был достаточно небольшой и экспортированное в XML средствами самого WordPress содержимое весило почти в 10 раз меньше - 6 мегабайт вместо 72 полной базы. Краткое расследование в интернете показало, что во всем виноваты так называемые ревизии записей, по умолчанию включенные в WordPress начиная с версии 2.6. Проще говоря, при каждом изменении записи движок сохраняет ее копию, чтобы потом можно было вернуться и сопоставить изменения. Таким образом, из 4700 строк в таблице wp_posts 4200 были заняты этими самыми ревизиями. Штатных средств удаления и отключения ревизий нет, проще всего использовать специальное расширение WP-Optimize - и базу оптимизирует.

Список ревизий из базы данных можно получить следующим запросом:

 SELECT *  FROM wp_posts WHERE post_type = "revision"; 

Отключаются они включением соответствующего параметра в конфигурационном файле

define('WP_POST_REVISIONS', 5); // 5 - максимальное число, для полного отключения - 0

или одним из специальных расширений

Disable and Turn Off Post Revisions Tracking in WordPress 2.6 or Above

How to Delete Existing WordPress Post Revisions Stored/Saved

Рубрика: Wordpress | Добавить комментарий

Особенности работы свойства BindingSource.Filter при связке нескольких элементов с одним источником данных

Задача: связать несколько визуальных элементов (гриды, комбо-боксы и тд) с одним источником данных, наложив на него разные фильтры. В принципе все просто - создаем несколько BindingSource и прописываем им разные выражения в свойство BindingSource.Filter.

Но если мы свяжем все BindingSource сразу с исходной DataTable, то получим весьма сюрреалистическую картину, каждый последующий фильтр будет накладываться сразу на все выборки, переписывая значения предыдущих. Выход прост - создаем для каждого элемента и BindingSource личный DataView и указываем в качестве источника данных именно его.

Рубрика: C# | Добавить комментарий