Как изменить раскладку клавиатуры в приложении на .Net C#

Сколько раз вы матерились про себя, начав набирать пароль на русском или русский текст на английском? Переключение раскладки в Windows не очень удобно и почти никто не пытается исправить это неудобство в своей программе. Хотя делается это очень просто. Не буду касаться тонкостей определения установленных в системе раскладок, возьму самый простой случай с русским компьютером и русско-английской раскладкой.

Установить русскую раскладку можно используя классы InputLanguage и CultureInfo:

 InputLanguage.CurrentInputLanguage =  InputLanguage.FromCulture(new System.Globalization.CultureInfo("ru-RU")); 

для американского варианта английского языка

 InputLanguage.CurrentInputLanguage =  InputLanguage.FromCulture(new System.Globalization.CultureInfo("en-US")); 

Другие раскладки устанавливаются аналогичным образом. Список возможных вариантов раскладок можно посмотреть здесь.

Как изменить внешний вид курсора в C# и WinForms

Самый распространенный случай - знаменитые "песочные часы" при ожиданиия завершения какой-либо операции. Меняется курсор очень просто (предполагает код внутри винформы) - достаточно использовать класс Cursor:

this.Cursor = Cursors.WaitCursor;
someVeryLongAndImportantFunction();
this.Cursor = Cursors.Default; 

Список возможных курсоров можно посмотреть в свойствах класса Cursors

Обработка ошибок в диалоговом окне - как предотвратить его закрытие, DialogResult и ShowDialog

Имеем абсолютно стандартное диалоговое окно с кнопками подтверждения и отмены, вызываемое по какому-то действию, например клику по кнопке:

 if(someDialogForm.ShowDialog() != DialogResult.OK) { return;} 

Но нам надо не просто получить данные из диалогового окна по кнопке "Ок", а еще и проверить их прямо в диалоговом окне и в случае какой-либо ошибки вернуться в диалоговое окно для повторного ввода данных.

Делается это очень простым, но несколько неочевидным способом, само собой проверка вешается на клик по кнопке подтверждения, но чтобы прервать закрытие дилогового окна надо изменть свойство DialogResult самой диалоговой формы

this.DialogResult = DialogResult.None;
return;

Обрабатываем ввод данных в колонку чекбоксов DataGridView - C#, checkbox colum, CurrentCellDirtyStateChanged

Имеем сетку DataGridView связанную с некой DataTable через BindingSource. Один из столбцов DataGridView содержит chekbox'ы - в нем надо ставить галочки. При изменении значения в любой ячейке этого столбца, включая удаление и добавление строк, надо проделать некие вычисления по данным DataGridView (точнее говоря связанной с ним DataTable), включая количество отмеченных chekbox'ов.

По умолчанию подобный столбец ведет себя крайне неестественно для конечного пользователя. Точнее говоря, на него распространяется стандартная модель поведения - зашли в ячейку, начали редактировать, закончили редактировать выйдя из ячейки или нажав Enter. Вот только все редактирование chekbox ограничивается одним мышиными кликом, на экране галочка ставится, но изменение данных происходит только при выборе другой ячейки или нажатии Enter. Нормального способа решения этой проблемы нет - все события, включая CellValueChanged, CellClick не позволяют получить доступ к измененному значению chekbox до выхода из режима редактирования.
Читать далее

Как удалить текущую строку/все строки из DataGridView/DataTable в C#/.Net

Имеем сетку DataGridView соединенную с таблицей DataTable (может входить в DataSet) с помощью BindingSource.

Чтобы удалить выбранную в датагриде строку надо использовать метод RemoveCurrent() класса BindingSource

testBindingSource.RemoveCurrent();

Все строки удаляет метод Clear(). Может показаться, что его тоже надо вызывать на BindingSource, но это вызывает ошибку ArgumentException с невнятным текстом "Невозможно очистить этот список." Дело в том, что BindingSource не может очистить DataTable, так что придется вызывать метод Clear() самой таблицы.

testDataTable.Clear();

Забавная ошибка в C# - namespace name "Word" could not be found

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

 Word.Range myRange; 

говорящей: The name 'Word' does not exist in the current context. Не сразу осознал, что все дело в том, как объявлено используемое пространство имен. Для работы с Word мы подключаем библиотеку Microsoft Office 11 Object Library и прописываем пространство имен, я сделал это так:

 using Microsoft.Office.Interop.Word;

а в изучаемом мною коде иначе

 using Word =  Microsoft.Office.Interop.Word;

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

 Range myRange;