Получить индекс столбца как постоянное значение - PullRequest
0 голосов
/ 18 января 2019

В настоящее время у меня есть такой код внутри dataGridView1_CellValidating event:

if(e.ColumnIndex == dataGridView1.Columns["FIRST"].Index)
{
    // Some code
}
else if(e.ColumnIndex == dataGridView1.Columns["Second"].Index)
{
    // Some code
}
else if(e.ColumnIndex == dataGridView1.Columns["Third"].Index)
{
    // Some code
}

И это так, потому что я не могу использовать его в выражении switch как:

switch(e.ColumnIndex)
{
    case dataGridView.Columns["First"].Index:
        break;
    case dataGridView.Columns["Second"].Index:
        break;
    case dataGridView.Columns["Third"].Index:
        break;
}

возвращает мне ошибку на case строке Expecting constant value.

Так, как я могу заставить эту работу?

Ответы [ 5 ]

0 голосов
/ 19 января 2019

Оператор 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;
}
0 голосов
/ 18 января 2019

Если вы не можете использовать сопоставление с образцом из 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();
}

Конечно, вы можете объявить Словарь в своем конструкторе и просто вызвать его в событии CellValidating.

0 голосов
/ 18 января 2019

Возможно, вы сначала задаете постоянные значения и присваиваете 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;
}
0 голосов
/ 18 января 2019

У меня был бы другой подход, использующий 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();
        }
    }
}

Выходы:

второй случай

0 голосов
/ 18 января 2019

Если вы действительно хотите использовать переключатель, вы можете использовать сопоставление с образцом в случае переключателя

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;
}
...