Какими персонажами вы должны и которые вы не должны убежать, действительно зависит от того, с чем вы работаете.
Для PCRE и большинства других так называемых Perl-совместимых ароматов избегайте этих внешних классы символов:
.^$*+?()[{\|
и эти внутренние классы символов:
^-]\
Для POSIX расширенных регулярных выражений (ERE), избегайте этих внешних классов символов (таких же, как PCRE):
.^$*+?()[{\|
Выключение любых других символов является ошибкой с POSIX ERE.
Внутри классов символов обратная косая черта является буквальным символом в регулярных выражениях POSIX. Вы не можете использовать его, чтобы избежать чего-либо. Вы должны использовать «умное размещение», если хотите включить метасимволы класса символов в виде литералов. Поместите ^ в любом месте, кроме как в начале, в начале, а в начале или в конце класса символов, чтобы соответствовать этим буквально, например:
[]^-]
В основных регулярных выражениях POSIX (BRE), это метасимволы, которые вам нужно убежать, чтобы подавить их смысл:
.^$*
Выпуски из круглых скобок и фигурных скобок в BRE дают им особый смысл, который их неописуемые версии имеют в ERE. Некоторые реализации (например, GNU) также придают особое значение другим символам при экранировании, например \? и +. Сброс символа, отличного от. ^ $ * () {}, Как правило, является ошибкой с BRE.
Внутри классов символов BRE следуют тому же правилу, что и ERE.
Если все это делает голова спина, возьмите копию RegexBuddy . На вкладке «Создать» нажмите «Вставить маркер», а затем «Литерал». RegexBuddy добавит экраны при необходимости.
У меня был бы другой подход, использующий Dictionnary
(из пространства имен System.Collections.Generic
) методов, построенных таким образом
Ключ - это индекс столбца в представлении данных («Первый», «Второе» ...)
Значение - это делегат метода, который нужно сделать (что заменяет ваш // some code
в каждом if / else if
Например:
/*
* This example is written for console application, that can be tested easily.
* The logic can be rewritten for WinForm
*/
static void TheFirstCase()
{
//This should be replaced by the differents actions you want to do
Console.WriteLine("first case");
}
static void TheSecondtCase()
{
Console.WriteLine("second case");
}
static void TheThirdCase()
{
Console.WriteLine("third case");
}
static void Main(string[] args)
{
Dictionary<string, Delegate> MyDic = new Dictionary<string, Delegate>
{
//If you need parameters in the TheFirstCase(), use new Action<TypeOfTheFirstParam, TypeOfTheSecondParam, ...>(TheFirstCase)
//If your Method needs to return something, use Func instead of Action
{ "First", new Action(TheFirstCase) },
{ "Second", new Action(TheSecondtCase) },
{ "Third", new Action(TheThirdCase) }
};
// in your question, this is e.ColumnIndex
var ValueInColIndex = 42;
// in your question, this is dataGridView.Columns
var DataGridViewDatas = new Dictionary<string, int>
{
{ "First", 0 },
{ "Second", 42 },
{ "Third", 69 }
};
foreach (var MyAction in MyDic)
{
if (DataGridViewDatas[MyAction.Key] == ValueInColIndex)
{
MyAction.Value.DynamicInvoke();
}
}
}
] Выходы:
второй регистр
blockquote>
Возможно, вы сначала создаете постоянные значения и присваиваете dataGridView.Columns ["First"]. Индексируйте его. Например:
int a = {given index}
const int IndexOfFirstCol = dataGridView.Columns["First"].Index;
const int IndexOfSecCol = dataGridView.Columns["Second"].Index;
затем
switch(a)
{
case IndexOfFirstCol:
//do smth
break;
case IndexOfSecCol:
//do smth
break;
}
Оператор switch жалуется, потому что часть «case» в выражении «требует» значения «CONSTANT». Оператор dataGridView.Columns["First"].Index
всегда будет возвращать одно и то же значение ... если вы не переместите столбец ... что вы можете сделать. Вот почему компилятор будет смотреть на перенастроенное значение из dataGridView.Columns["First"].Index
как НЕ «константа».
Это имеет смысл в том факте, что «индекс столбца» для столбца с именем «First» может быть в ЛЮБОМ индексе столбца в сетке… Отсюда и ошибка.
Возможное решение состоит в том, чтобы получить текущее значение строки «Имя» столбцов, а затем отключить столбец «Имя», как показано ниже.
string columnName = dataGridView.Columns[e.ColumnIndex].Name;
switch (columnName) {
case "First":
MessageBox.Show("Cell Validated is in 'FIRST' column");
break;
case "Second":
MessageBox.Show("Cell Validated is in 'Second' column");
break;
case "Third":
MessageBox.Show("Cell Validated is in 'Third' column");
break;
}
Если вы действительно хотите использовать переключатель, вы можете использовать сопоставление с образцом в случае переключателя
PS: для C # 7.0 или выше
switch(e.ColumnIndex)
{
case var _ when (dataGridView.Columns["First"].Index == e.ColumnIndex):
break;
case var _ when (dataGridView.Columns["Second"].Index == e.ColumnIndex):
break;
case var _ when (dataGridView.Columns["Third"].Index == e.ColumnIndex):
break;
}
Если вы не можете использовать сопоставление с образцом из C # 7.0, есть и другой способ - использовать диктонары, где ваши ключи - это функции, проверяющие условия (случаи), а значения - это действия, которые вы хотите выполнить. Для вашего кода это будет выглядеть так:
private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
var caseDictionary = new Dictionary<Func<bool>, Action>()
{
{ () => (e.ColumnIndex == dataGridView1.Columns["First"].Index), () => { MessageBox.Show("First");}},
{ () => (e.ColumnIndex == dataGridView1.Columns["Second"].Index), () => { MessageBox.Show("Second");}},
{ () => (e.ColumnIndex == dataGridView1.Columns["Third"].Index), () => { MessageBox.Show("Third");}}
};
caseDictionary.Where(caseRecord => caseRecord.Key()).Select(action => action.Value).FirstOrDefault()?.Invoke();
}
Конечно, вы можете объявить Dictionary в своем конструкторе и просто вызвать его в событии CellValidating
.