Lass mich das für dich GOOGLEn!
http://lmgtfy.com/
Эта страничка посвящается всем тем, кто не желает самостоятельно воспользоваться поисковиком, а достает всех своими вопросами.
Пользоваться примерно так:
http://lmgtfy.com/?q=как+правильно+искать+информацию
воскресенье, 21 ноября 2010 г.
воскресенье, 24 октября 2010 г.
Perfomance Counter. Счетчик производительности
Когда мы хотим измерить производительность кода, нас интересует время, потраченое на его выполнение. Для этого можно "запомнить" время ДО, и время ПОСЛЕ, вычислить разницу и анализировать результат. В этом случае считается, что процессор все время будет выполнять только этот код. Но на практике может получится так, что во время выполения поток дойдет до середины, процессор переключится на другие потоки, обойдет их, и через некоторое время вернется к нашему. Естественно измерения в этом случае некорректны.
С учетом вышеизложенного, для точных расчетов я использую следующий класс (сперто где-то с просторов интернета):
С учетом вышеизложенного, для точных расчетов я использую следующий класс (сперто где-то с просторов интернета):
class PerfCounter
{
private static TimeSpan spStartKernelTime;
private static TimeSpan spStartUserTime;
private static ProcessThread procThread;
private static Int32 idCurrentThread;
[DllImport("kernel32.Dll", SetLastError = true)]
public static extern UInt32 GetCurrentThreadId();
public static bool StartCountOnThread()
{
idCurrentThread = (Int32)GetCurrentThreadId();
try
{
foreach (ProcessThread prThread in Process.GetCurrentProcess().Threads)
{
if (prThread.Id == idCurrentThread)
{
procThread = prThread;
spStartKernelTime = prThread.TotalProcessorTime;
spStartUserTime = prThread.UserProcessorTime;
return true;
}
}
}
catch (System.Exception e)
{
System.Console.WriteLine(e.Message);
//System.Windows.Forms.MessageBox.Show(e.Message);
return false;
}
return false;
}
public static TimeSpan FinishCountOnThread()
{
try
{
foreach (ProcessThread prThread in Process.GetCurrentProcess().Threads)
{
if (prThread.Id == idCurrentThread)
{
return prThread.TotalProcessorTime +
prThread.UserProcessorTime -
spStartKernelTime - spStartUserTime;
}
}
}
catch (System.Exception e)
{
//System.Windows.Forms.MessageBox.Show(e.Message);
System.Console.WriteLine(e.Message);
return TimeSpan.Zero;
}
return TimeSpan.Zero; ;
}
}
* This source code was highlighted with Source Code Highlighter.
воскресенье, 17 октября 2010 г.
Ранкинг (Ranking). SQL запросы с рангом (Rank).
Ранкинг (Ranking) - это предоставление информации о соответствии найденной записи определенному запросу. Это соответствие в простейшем случае можно отобразить в процентном соостветсвии. Т.е. записи удовлетворяющие всем критериям имеют 100%-ный ранкинг.
Реализация ранкинга может показаться достаточно сложной задачей. Но это только так кажется. SQL может взять эту задачу на себя! Для примера я использовал MySQL, реально использовал MSSQL.
Итак, таблица:
Наполним данными:
Найдем записи, которые соответсвуют одному из трех критериев:
- все старше 25;
- все младше 35;
- имена начинаются на "P";
Запрос может выглядеть так:
А результат запроса, так:
id, name, age
------------
1,'Ralf', 20
2,'Peter', 30
3,'Patrick',40
Добавим ранкинг (ranking). Объяснять не буду, все очень просто:
Результат:
id, name, age, rank
------------
1,'Ralf', 20, null
2,'Peter', 30, null
3,'Patrick', 40, null
Почти то, что нужно, но есть проблема с приведением арфиметического результа к null:
Для этого в MySql можно использовать функцию IFNULL (в MSSQL это функция ISNULL):
Результат:
id, name, age, rank
------------
1,'Ralf', 20, 33.333
2,'Peter', 30, 100.000
3,'Patrick', 40, 66.666
Реализация ранкинга может показаться достаточно сложной задачей. Но это только так кажется. SQL может взять эту задачу на себя! Для примера я использовал MySQL, реально использовал MSSQL.
Итак, таблица:
CREATE TABLE `test_db`.`person` (
`id` INT NOT NULL,
`name` VARCHAR (100),
`age` int ,
PRIMARY KEY (`id`)
)
Наполним данными:
INSERT INTO test_db.person VALUES (1,'Ralf', 20),(2,'Peter', 30),(3,'Patrick', 40);
Найдем записи, которые соответсвуют одному из трех критериев:
- все старше 25;
- все младше 35;
- имена начинаются на "P";
Запрос может выглядеть так:
SELECT p.id, p.name, p.age FROM test_db.person p
WHERE age > 25 OR age < 35 OR name Like 'P%'
А результат запроса, так:
id, name, age
------------
1,'Ralf', 20
2,'Peter', 30
3,'Patrick',40
Добавим ранкинг (ranking). Объяснять не буду, все очень просто:
SELECT p.id, p.name, p.age, (100/3)*under1.hit + (100/3)*under2.hit + (100/3)*under3.hit AS rank FROM test_db.person p
LEFT JOIN (Select id, 1 As hit from test_db.person WHERE age > 25) AS under1 On under1.id = p.id
LEFT JOIN (Select id, 1 As hit from test_db.person WHERE age < 35) AS under2 On under2.id = p.id LEFT JOIN (Select id, 1 As hit from test_db.person WHERE name like 'p%') AS under3 On under3.id = p.id WHERE age > 25 OR age < 35 OR name like 'p%'
Результат:
id, name, age, rank
------------
1,'Ralf', 20, null
2,'Peter', 30, null
3,'Patrick', 40, null
Почти то, что нужно, но есть проблема с приведением арфиметического результа к null:
Для этого в MySql можно использовать функцию IFNULL (в MSSQL это функция ISNULL):
SELECT p.id, p.name, p.age, (100/3)*IFNULL(under1.hit, 0) + (100/3)*IFNULL(under2.hit,0) + (100/3)*IFNULL(under3.hit,0) AS rank FROM test_db.person p
LEFT JOIN (Select id, 1 As hit from test_db.person WHERE age > 25) AS under1 On under1.id = p.id
LEFT JOIN (Select id, 1 As hit from test_db.person WHERE age < 35) AS under2 On under2.id = p.id LEFT JOIN (Select id, 1 As hit from test_db.person WHERE name like 'p%') AS under3 On under3.id = p.id WHERE age > 25 OR age < 35 OR name like 'p%'
Результат:
id, name, age, rank
------------
1,'Ralf', 20, 33.333
2,'Peter', 30, 100.000
3,'Patrick', 40, 66.666
суббота, 16 октября 2010 г.
Запуск дополнительного X-Server.
Обычно Linux десктоп дистрибутив запускает одну инстанцию X-Server, которая работает в "7"-ом терминале (Alt+Ctrl+F7). Эта инстанция работает с первым X-дисплеем (X-Display). Чтобы запустить программу в другой инстанции нужно:
Примеры:
$ xinit gedit -- :1
$ xinit nexuiz -- :1
Замечания:
- выбрать нужный терминал (Alt+Ctrl+Fx)
- войти в терминал под своим именем паролем
- $ xinit _prg_ -- :1 (здесь :1 - номер следующего свободного X-дисплея, нумерация с нуля)
Примеры:
$ xinit gedit -- :1
$ xinit nexuiz -- :1
Замечания:
- Так можно запускать игры или "проблемные" программки, которые приводят с сбою графического сервера;
- Окна программ не имеют атрибутов вашего рабочего окружения (GNOME, KDE);
- Закрытие зависших программ - Ctrl+C
- Информация должна быть действительна во многих Linux-дистрибутивах, проверено на Ubuntu 10.10 (64bit)
среда, 6 октября 2010 г.
XDocument. Работа с элементами без явного указания пространства имен по умолчанию (Default Namespace)
Если вы используете XDocument, Xml которого содержит явное пространство имен по умолчанию, то во время разбора элементов придется его явно указывать. Для ясности кусочки кода:
Чтобы получить значение тега "Name", придется выполнить следующий код:
Немного раздражительно, не правда ли?
Для облегчения страданий я создал следующие методы-расширения
Теперь работа с документом происходит обычным способом:
<Data xmlns="http://selo-blog.blogspot.com/">
<Name>Иван</Name>
<Gender>мужской</Gender>
</Data>
Чтобы получить значение тега "Name", придется выполнить следующий код:
XDocument xDoc = XDocument.Parse(inputString);
XNamespace xSpace = "http://selo-blog.blogspot.com/";
String name = xDoc.Root.Element(xSpace + "Name").Value;
Немного раздражительно, не правда ли?
Для облегчения страданий я создал следующие методы-расширения
public static class Extensions {
public static XElement xElement(this XElement xParent, String name) {
return xParent.Element(xParent.Name.Namespace + name);
}
public static IEnumerable<XElement> xElements(this XElement xParent, String name) {
return xParent.Elements(xParent.Name.Namespace + name);
}
}
Теперь работа с документом происходит обычным способом:
String name = xDoc.Root.xElement("Name").Value;
* This source code was highlighted with Source Code Highlighter.
понедельник, 20 сентября 2010 г.
WinForms. Простой доступ к контексту приложения.
Что бы обеспечить простой досуп к контексту приложения (ApplicationContext) я использовал слудующий подход:
Ну и теперь, собственно, в любом месте приложения:
MessageBox.Show(AppContext.Current.I + "");
public class AppContext : ApplicationContext
{
public static AppContext Current { get; private set; }
public AppContext() {
if (Current == null)
Current = this;
this.init();
}
public AppContext(Form mainForm) : this() {
this.MainForm = mainForm;
}
private void init() {
// ...
}
int i = 0;
public int I { get { return i++; } }
}
* This source code was highlighted with Source Code Highlighter.
Ну и теперь, собственно, в любом месте приложения:
MessageBox.Show(AppContext.Current.I + "");
понедельник, 5 июля 2010 г.
MS SQL. Замена NULL на другие значения
Встретился с небольшой проблемкой, когда в математическом выражении один из операндов является NULL, то результат выражения становится нуль. Вот нашел на просторах интернета по этому поводу следующую информацию. А мне нужно было интерпретировать NULL в 0. Для этого, к счастью, есть в MS SQL функция:
ISNULL ( check_expression , replacement_value )
Например:
SELECT Description, DiscountPct, MinQty, ISNULL(MaxQty, 0.00) AS 'Max Quantity'
FROM Sales.SpecialOffer;
ISNULL ( check_expression , replacement_value )
Например:
SELECT Description, DiscountPct, MinQty, ISNULL(MaxQty, 0.00) AS 'Max Quantity'
FROM Sales.SpecialOffer;
среда, 19 мая 2010 г.
Стандартные операторы запросов LINQ. Справочник
Эту информацию я скомуниздил здесь.
Агрегатные функции
Aggregate
Применяет к последовательности пользовательский метод.
Average
Вычисляет среднее для числовой последовательности.
Count
Возвращает количество элементов в последовательности (целочисленное значение).
LongCount
Возвращает количество элементов в последовательности (значение в диапазоне LongInt).
Min
Возвращает наименьшее значение для числовой последовательности.
Max
Возвращает наибольшее значение для числовой последовательности.
Sum
Складывает члены числовой последовательности.
Конкатенация
Concat
Соединяет две последовательности в одну.
Преобразование
Cast
Преобразует элементы последовательности в элемены указанного типа.
OfType
Выбирает из элементов последовательности элемены указанного типа.
ToArray
Возвращает массив из элементов последовательности.
ToDictionary
Возвращает словарь из элементов последовательности.
ToList
Возвращает список из элементов последовательности.
ToLookup
Возвращает результаты поиска по последовательности.
ToSequence
Возвращает последовательность IEnumerable.
Элемент
DefaultIfEmpty
Создает стандартный элемент для пустой последовательности.
ElementAt
Возвращает элемент последовательности по указанному индексу.
ElementAtOrDefault
Возвращает элемент по указанному индексу или стандартный элемент (если индекс вышел за пределы диапазона).
First
Возвращает первый элемент последовательности.
FirstOrDefault
Возвращает первый элемент последовательности или стандартный элемент (если нужный элемент не найден).
Last
Возвращает последний элемент последовательности.
LastOrDefault
Возвращает последний элемент последовательности или стандартный элемент (если нужный элемент не найден).
Single
Возвращает единственный элемент последовательности.
SingleOrDefault
Возвращает единственный элемент последовательности или стандартный элемент (если нужный элемент не найден).
Равенство
SequenceEqual
Проверяет эквивалентность двух последовательностей.
Создание
Empty
Создает пустую последовательность.
Range
Создает последовательность в соответствии с заданным диапазоном.
Repeat
Создает последовательность, повторяя значение заданное количество раз.
Группировка
GroupBy
Группирует элементы последовательности указанным образом.
Присоединение
GroupJoin
Выполняет группированное соединение двух последовательностей.
Join
Выполняет внутреннее соединение двух последовательностей.
Упорядочение
OrderBy
Упорядочивает элементы последовательности по заданным значениям в порядке возрастания.
OrderByDescending
Упорядочивает элементы последовательности по заданным значениям в порядке убывания.
ThenBy
Упорядочивает элементы уже упорядоченной последовательности в порядке возрастания.
ThenByDescending
Упорядочивает элементы уже упорядоченной последовательности в порядке убывания.
Reverse
Зеркально отображает порядок расположения элементов в последовательности.
Разделение на части
Skip
Возвращает последовательность, в которой указанное число элементов пропущено.
SkipWhile
Возвращает последовательность, в которой пропущены элементы, не соответствующие указанному условию.
Take
Возвращает последовательность, в которую включается указанное число элементов.
TakeWhile
Возвращает последовательность, в которую включаются элементы, соответствующие указанному условию.
Проекция
Select
Создает проекцию части последовательности.
SelectMany
Создает проекцию части последовательности по принципу «один ко многим».
Кванторы
All
Определяет соответствие всех элементов последовательности указанным условиям.
Any
Определяет, есть ли в последовательность элементы, удовлетворяющие указанным условиям.
Contains
Определяет, есть ли в последовательности указанный элемент.
Ограничение
Where
Сортирует члены последовательности.
Настройка
Distinct
Возвращает последовательность без повторяющихся элементов.
Except
Возвращает последовательность, представляющую собой разность двух других последовательностей.
Intersect
Возвращает последовательность, представляющую собой пересечение двух других последовательностей.
Union
Возвращает последовательность, представляющую собой объединение двух других последовательностей.
Агрегатные функции
Aggregate
Применяет к последовательности пользовательский метод.
Average
Вычисляет среднее для числовой последовательности.
Count
Возвращает количество элементов в последовательности (целочисленное значение).
LongCount
Возвращает количество элементов в последовательности (значение в диапазоне LongInt).
Min
Возвращает наименьшее значение для числовой последовательности.
Max
Возвращает наибольшее значение для числовой последовательности.
Sum
Складывает члены числовой последовательности.
Конкатенация
Concat
Соединяет две последовательности в одну.
Преобразование
Cast
Преобразует элементы последовательности в элемены указанного типа.
OfType
Выбирает из элементов последовательности элемены указанного типа.
ToArray
Возвращает массив из элементов последовательности.
ToDictionary
Возвращает словарь из элементов последовательности.
ToList
Возвращает список из элементов последовательности.
ToLookup
Возвращает результаты поиска по последовательности.
ToSequence
Возвращает последовательность IEnumerable.
Элемент
DefaultIfEmpty
Создает стандартный элемент для пустой последовательности.
ElementAt
Возвращает элемент последовательности по указанному индексу.
ElementAtOrDefault
Возвращает элемент по указанному индексу или стандартный элемент (если индекс вышел за пределы диапазона).
First
Возвращает первый элемент последовательности.
FirstOrDefault
Возвращает первый элемент последовательности или стандартный элемент (если нужный элемент не найден).
Last
Возвращает последний элемент последовательности.
LastOrDefault
Возвращает последний элемент последовательности или стандартный элемент (если нужный элемент не найден).
Single
Возвращает единственный элемент последовательности.
SingleOrDefault
Возвращает единственный элемент последовательности или стандартный элемент (если нужный элемент не найден).
Равенство
SequenceEqual
Проверяет эквивалентность двух последовательностей.
Создание
Empty
Создает пустую последовательность.
Range
Создает последовательность в соответствии с заданным диапазоном.
Repeat
Создает последовательность, повторяя значение заданное количество раз.
Группировка
GroupBy
Группирует элементы последовательности указанным образом.
Присоединение
GroupJoin
Выполняет группированное соединение двух последовательностей.
Join
Выполняет внутреннее соединение двух последовательностей.
Упорядочение
OrderBy
Упорядочивает элементы последовательности по заданным значениям в порядке возрастания.
OrderByDescending
Упорядочивает элементы последовательности по заданным значениям в порядке убывания.
ThenBy
Упорядочивает элементы уже упорядоченной последовательности в порядке возрастания.
ThenByDescending
Упорядочивает элементы уже упорядоченной последовательности в порядке убывания.
Reverse
Зеркально отображает порядок расположения элементов в последовательности.
Разделение на части
Skip
Возвращает последовательность, в которой указанное число элементов пропущено.
SkipWhile
Возвращает последовательность, в которой пропущены элементы, не соответствующие указанному условию.
Take
Возвращает последовательность, в которую включается указанное число элементов.
TakeWhile
Возвращает последовательность, в которую включаются элементы, соответствующие указанному условию.
Проекция
Select
Создает проекцию части последовательности.
SelectMany
Создает проекцию части последовательности по принципу «один ко многим».
Кванторы
All
Определяет соответствие всех элементов последовательности указанным условиям.
Any
Определяет, есть ли в последовательность элементы, удовлетворяющие указанным условиям.
Contains
Определяет, есть ли в последовательности указанный элемент.
Ограничение
Where
Сортирует члены последовательности.
Настройка
Distinct
Возвращает последовательность без повторяющихся элементов.
Except
Возвращает последовательность, представляющую собой разность двух других последовательностей.
Intersect
Возвращает последовательность, представляющую собой пересечение двух других последовательностей.
Union
Возвращает последовательность, представляющую собой объединение двух других последовательностей.
вторник, 11 мая 2010 г.
XDocument в XMLDocument и наоборот
У меня в примерах
XmlDocument xmlDoc;
XDocument xDoc;
XMLDocument To XMLDocument
Самый простой, но и пожалуй самый медленный способ:
Второй вариант:
XMLDocument To XMLDocument
Очень простой способ:
И чего это я раньше следующим монстром пользовался?
XmlDocument xmlDoc;
XDocument xDoc;
XMLDocument To XMLDocument
Самый простой, но и пожалуй самый медленный способ:
XDocument.Parse(xmlDoc.OuterXml);
Второй вариант:
using (var nodeReader = new XmlNodeReader(xmlDoc)) {
nodeReader.MoveToContent();
xDoc = XDocument.Load(nodeReader);
}
XMLDocument To XMLDocument
Очень простой способ:
xmlDoc.Load(xDoc.CreateReader());
И чего это я раньше следующим монстром пользовался?
using (MemoryStream memStr = new MemoryStream()) {
using (XmlWriter writer = XmlWriter.Create(memStr)) {
xDoc.Save(writer);
}
memStr.Position = 0;
using (XmlReader reader = XmlReader.Create(memStr)) {
xmlDoc.Load(reader);
}
}
вторник, 4 мая 2010 г.
Изменение имени проекта (сборки) в Visual Studio 2008
Вообще-то есть уже куча руководств, как можно проделать сие.
Например здесь.
http://social.msdn.microsoft.com/Forums/en-US/csharpide/thread/d4133fb7-57e1-44f2-a319-a63e7921ff0a
Но я решил запостить последовательность действий, которую выполнил я. При этом я не "поломал" проект и не потерял историю изменений для TFS. Итак VS 2008, TFS.
1. Выбрал проект в Експлорере проектов -> переименовал;
3. Свойства проекта -> Установил имя сборки и имя пространств имен. Тут же заглянул в информацию сборки и изменил название сборки (AssemblyInfo.cs);
4. В окне Quellcodeverwaltuns-Explorer переименовал папку. При этом проект закрылся и имя папки было на диске физически переименованно;
5. После того как открыл проект, студия ругнулась, что не нашла того самого проекта (или не смогла открыть). В эксплорере проектов он выделен другим цветом и пустой.
6. В свойствах проекта ранее доступное только для чтение свойство Projektordner становится доступным для изменения. Указал новый путь.
Все.
Например здесь.
http://social.msdn.microsoft.com/Forums/en-US/csharpide/thread/d4133fb7-57e1-44f2-a319-a63e7921ff0a
Но я решил запостить последовательность действий, которую выполнил я. При этом я не "поломал" проект и не потерял историю изменений для TFS. Итак VS 2008, TFS.
1. Выбрал проект в Експлорере проектов -> переименовал;
3. Свойства проекта -> Установил имя сборки и имя пространств имен. Тут же заглянул в информацию сборки и изменил название сборки (AssemblyInfo.cs);
4. В окне Quellcodeverwaltuns-Explorer переименовал папку. При этом проект закрылся и имя папки было на диске физически переименованно;
5. После того как открыл проект, студия ругнулась, что не нашла того самого проекта (или не смогла открыть). В эксплорере проектов он выделен другим цветом и пустой.
6. В свойствах проекта ранее доступное только для чтение свойство Projektordner становится доступным для изменения. Указал новый путь.
Все.
вторник, 23 марта 2010 г.
Автоматическое определение CultureInfo для установленных сателитных сборок
На днях понадобилось в программе автоматически определять, для каких языков в программе существуют сателитные сборки (Satellite Assemblies). Для чего это нужно? А понадобилось для того, что бы процесс локализации приложения на новый язык был максимально простым. В установленную программу просто добавляются локализированные ресурсы в виде сателитных сборок, и никаких перекомпиляций уже не требуется. Т.к. я не нашел штатных средств для извлечения информации об установленных сборках, написал свою реализацию.
private List<CultureInfo> GetInstalledCultures() {
// declare result
List<CultureInfo> result = new List<CultureInfo>();
// define paths
String rootPath = Path.GetDirectoryName(this.GetType().Assembly.Location);
String assemblyName = this.GetType().Assembly.GetName().Name;
String satAssemblyName = assemblyName + ".resources.dll";
// scan directory for sat assemblies
DirectoryInfo root_di = new DirectoryInfo(rootPath);
foreach (DirectoryInfo di in root_di.GetDirectories()) {
String satAssemblyPath = Path.Combine(di.FullName, satAssemblyName);
if (File.Exists(satAssemblyPath)) {
try {
// check that folder contains the correct data
CultureInfo ci = new CultureInfo(di.Name);
Assembly satAssembly = this.GetType().Assembly.GetSatelliteAssembly(ci);
// successful
result.Add(ci);
}
catch {
// Nothing. Test for the creating the CultureInfo and Assembly objects;
}
}
}
// result
return result;
}
* This source code was highlighted with Source Code Highlighter.
вторник, 12 января 2010 г.
Заполнение параметров значениями для SQL-выражения
Понадобилось протестировать созданное динамически SQL-выражение с параметрами, типа
Чтобы выполнить такой запрос в окне запросов SQL Server Management Studio, необходимо объявить переменные-параметры и заполнить их значениями. Делается это так:
Declare @param uniqueidentifier
Set @param = '5792c959-33b4-47eb-a824-b74d32295506'
Также удалось использовать параметры следующих типов:
Строка:
DECLARE @param nvarchar(255)
SET @param = 'Dr%'
Целое число:
DECLARE @param int
SET @param = 123
Дата-время:
Declare @param DateTime
Set @param = '01/12/2010 14:02:17'
Select * From Person
Where ID = @param
Чтобы выполнить такой запрос в окне запросов SQL Server Management Studio, необходимо объявить переменные-параметры и заполнить их значениями. Делается это так:
Declare @param uniqueidentifier
Set @param = '5792c959-33b4-47eb-a824-b74d32295506'
Также удалось использовать параметры следующих типов:
Строка:
DECLARE @param nvarchar(255)
SET @param = 'Dr%'
Целое число:
DECLARE @param int
SET @param = 123
Дата-время:
Declare @param DateTime
Set @param = '01/12/2010 14:02:17'
Управление узлами в TreeView (WinForms)
В данной статье представленны исходные коды для следующих операций управления узлами (TreeNode) в элементе управления TreeView:
1) Переместить узел вверх
2) Переместить узел вниз
3) Переместить узел в список родительских узлов
4) Переместить узел в список узлов вышестоящего узла
Речь идет о языке программирования C# и WinForms.
Вот интрефейс программы:
Обработчик кнопки для заполнения TreeView тестовыми элементами TreeNode (нижняя в правом углу):
Вот код для определенных операций:
1) Узел вверх:
2) Узел вниз:
3) Узел влево:
4) Узел вправо:
Интрефейс пользователя подсказывает, какие операции доступны для выбранного элемента. Об этом заботится следующая функция:
Ее вызываю в момент создания формы и по событию AfterSelect элемента управления TreeView
1) Переместить узел вверх
2) Переместить узел вниз
3) Переместить узел в список родительских узлов
4) Переместить узел в список узлов вышестоящего узла
Речь идет о языке программирования C# и WinForms.
Вот интрефейс программы:
Обработчик кнопки для заполнения TreeView тестовыми элементами TreeNode (нижняя в правом углу):
int i = 0;
private void newNodeButton_Click(object sender, EventArgs e)
{
// create node
TreeNode newNode = new TreeNode(String.Format("Node {0}", i++));
// add node in tree view
if (treeView.SelectedNode != null)
treeView.SelectedNode.Nodes.Add(newNode);
else
treeView.Nodes.Add(newNode);
}
* This source code was highlighted with Source Code Highlighter.
Вот код для определенных операций:
1) Узел вверх:
private void upButton_Click(object sender, EventArgs e)
{
if (treeView.SelectedNode != null
&& treeView.SelectedNode.PrevNode != null)
{
// define edit collection
TreeNodeCollection editNodes;
if (treeView.SelectedNode.Parent != null)
editNodes = treeView.SelectedNode.Parent.Nodes;
else
editNodes = treeView.Nodes;
// define indexes
int indexSelectedNode = treeView.SelectedNode.Index;
int indexPreviousNode = treeView.SelectedNode.PrevNode.Index;
// store node
TreeNode selectedNode = treeView.SelectedNode;
// swap
editNodes.RemoveAt(indexSelectedNode);
editNodes.Insert(indexPreviousNode, selectedNode);
// select node
treeView.SelectedNode = selectedNode;
}
}
* This source code was highlighted with Source Code Highlighter.
2) Узел вниз:
private void downButton_Click(object sender, EventArgs e)
{
if (treeView.SelectedNode != null
&& treeView.SelectedNode.NextNode != null)
{
// define edit collection
TreeNodeCollection editNodes;
if (treeView.SelectedNode.Parent != null)
editNodes = treeView.SelectedNode.Parent.Nodes;
else
editNodes = treeView.Nodes;
// define indexes
int indexSelectedNode = treeView.SelectedNode.Index;
int indexNextNode = treeView.SelectedNode.NextNode.Index;
// store node
TreeNode selectedNode = treeView.SelectedNode;
// swap
editNodes.RemoveAt(indexSelectedNode);
editNodes.Insert(indexNextNode, selectedNode);
// select node
treeView.SelectedNode = selectedNode;
}
}
* This source code was highlighted with Source Code Highlighter.
3) Узел влево:
private void leftButton_Click(object sender, EventArgs e)
{
if (treeView.SelectedNode != null
&& treeView.SelectedNode.Parent != null)
{
// define edit collection
TreeNodeCollection editNodes;
if (treeView.SelectedNode.Parent.Parent != null)
editNodes = treeView.SelectedNode.Parent.Parent.Nodes;
else
editNodes = treeView.Nodes;
// store node
TreeNode selectedNode = treeView.SelectedNode;
// define indexes
int indexSelectedNode = treeView.SelectedNode.Index;
int indexParentNode = treeView.SelectedNode.Parent.Index;
// move node
treeView.SelectedNode.Parent.Nodes.Remove(selectedNode);
editNodes.Insert(indexParentNode + 1, selectedNode);
// select node
treeView.SelectedNode = selectedNode;
}
}
* This source code was highlighted with Source Code Highlighter.
4) Узел вправо:
private void rightButton_Click(object sender, EventArgs e)
{
if (treeView.SelectedNode != null
&& treeView.SelectedNode.PrevNode != null)
{
// define edit collection
TreeNodeCollection editNodes;
if (treeView.SelectedNode.Parent != null)
editNodes = treeView.SelectedNode.Parent.Nodes;
else
editNodes = treeView.Nodes;
// store node
TreeNode selectedNode = treeView.SelectedNode;
TreeNode previousNode = selectedNode.PrevNode;
// move node
editNodes.Remove(selectedNode);
previousNode.Nodes.Add(selectedNode);
// select node
treeView.SelectedNode = selectedNode;
}
}
* This source code was highlighted with Source Code Highlighter.
Интрефейс пользователя подсказывает, какие операции доступны для выбранного элемента. Об этом заботится следующая функция:
private void updateEnablingButtons()
{
upButton.Enabled = (treeView.SelectedNode != null
&& treeView.SelectedNode.PrevNode != null);
downButton.Enabled = (treeView.SelectedNode != null
&& treeView.SelectedNode.NextNode != null);
leftButton.Enabled = (treeView.SelectedNode != null
&& treeView.SelectedNode.Parent != null);
rightButton.Enabled = (treeView.SelectedNode != null
&& treeView.SelectedNode.PrevNode != null);
}
* This source code was highlighted with Source Code Highlighter.
Ее вызываю в момент создания формы и по событию AfterSelect элемента управления TreeView
воскресенье, 3 января 2010 г.
Regex. Поиск слова между кавычками
Дана строка:
что-то здесь Ключ1="Значение" Ключ2="Другое значение" здесь еще кой-чего.
Найти значение первого ключа без кавычек:
^.*Ключ1="(?<1>([.]|[^"])*)".*$
Результат:
Значение
что-то здесь Ключ1="Значение" Ключ2="Другое значение" здесь еще кой-чего.
Найти значение первого ключа без кавычек:
^.*Ключ1="(?<1>([.]|[^"])*)".*$
Результат:
Значение
Подписаться на:
Сообщения (Atom)