Derzeit habe ich Code wie diesen in dataGridView1_CellValidating Ereignis:

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
}

Und es ist so, weil ich es nicht in switch-Anweisungen verwenden kann wie:

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

Gibt mir einen Fehler in der Zeile case Expecting constant value zurück.

Wie kann ich das zum Laufen bringen?

0
Aleksa Ristic 18 Jän. 2019 im 10:57

5 Antworten

Beste Antwort

Die switch-Anweisung beschwert sich, weil der "case" -Teil der Anweisung "einen" CONSTANT "-Wert erfordert. Die Anweisung dataGridView.Columns["First"].Index gibt immer den gleichen Wert zurück ... es sei denn, Sie verschieben die Spalte ... was Sie tun können. Aus diesem Grund wird der Compiler den neu abgestimmten Wert von dataGridView.Columns["First"].Index NICHT als "Konstante" betrachten.

Dies ist insofern sinnvoll, als der "Spaltenindex" für die Spalte mit dem Namen "First" bei JEDEM Spaltenindex im Raster liegen könnte ... Daher der Fehler.

Eine mögliche Lösung besteht darin, den Zeichenfolgenwert der aktuellen Spalte "Name" abzurufen und dann die Spalte "Name" wie unten beschrieben auszuschalten.

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;
}
1
JohnG 19 Jän. 2019 im 03:08

Wenn Sie wirklich einen Schalter verwenden möchten, können Sie den Mustervergleich im Schalterfall verwenden

PS: Für C # 7.0 oder höher

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;
}
1
Anu Viswan 18 Jän. 2019 im 08:08

Möglicherweise erstellen Sie zuerst konstante Werte und weisen dataGridView.Columns ["First"]. Index zu. Beispielsweise:

int a = {given index}
const int IndexOfFirstCol = dataGridView.Columns["First"].Index;
const int IndexOfSecCol = dataGridView.Columns["Second"].Index;

Dann,

switch(a)
{
    case IndexOfFirstCol:
      //do smth
      break;
    case IndexOfSecCol:
      //do smth
      break;
}
0
Alvan Rahimli 18 Jän. 2019 im 08:32

Wenn Sie den Mustervergleich ab C # 7.0 nicht verwenden können, gibt es auch eine andere Möglichkeit, Diktaturen zu verwenden, bei denen Ihre Tasten Funktionen sind, die die Bedingungen (Fälle) überprüfen, und die Werte die Aktionen sind, die Sie ausführen möchten. Für Ihren Code würde es so aussehen:

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();
}

Sie können das Wörterbuch natürlich in Ihrem Konstruktor deklarieren und es einfach im Ereignis CellValidating aufrufen.

0
Code Pope 18 Jän. 2019 im 08:36

Ich hätte einen anderen Ansatz, bei dem ein Dictionnary (aus dem Namespace System.Collections.Generic) von Methoden verwendet wird, die auf diese Weise erstellt wurden

Der Schlüssel ist der Index der Spalte in der Datagrid-Ansicht ("First", "Second" ...)

Der Wert ist ein Delegat für die auszuführende Methode (was ersetzt Ihr // some code in jedem if / else if

Zum Beispiel :

/*
 * 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();
        }
    }
}

Ausgänge:

zweiter Fall

0
Cid 18 Jän. 2019 im 08:39