Domanda

Ho un DataGridView con

myGridView.DataSource = GetSomeData()


// method called
public IQueryable GetSomeData()
{
    var source = from r in records
                 select r;

    return source;    // made correction from 'r' to 'source'
}

GetSomeData() riempie il DataGridView come previsto. L'utente selezionerà una riga di modifica che poi passa i dati di riga di un modulo. Dal momento che il DataGridViewRow.DataBoundItem è un tipo anonimo, come posso passare DataBoundItem?

Mi aspettavo che la mia DataBoundItem sarebbe IQueryable - errato. Ecco le informazioni dal debugger sulla proprietà DataBoundItem:

  

DataBoundItem {CustomerID = "3133",   Last_Name = "Smith", First_Name =   "John", AccountNumber = "JS3133",   ActiveYN = True}

Una volta che i dati vengono passati alla nuova forma, mi piacerebbe fare qualcosa di simile:

txtFName.Text = SomeEnumeratedObject["First_Name"];
txtLName.Text = SomeEnumeratedObject["Last_Name"];

Tutte le idee su come posso fare questo? Sarebbe ancora meglio, IMO, se i controlli sul nuovo modulo potrebbe in qualche modo essere legati a SomeEnumeratedObject.

sarebbe possibile interrogare il DataBoundItem con LINQ?

Modifica:

metodo modificato:

public DataView GetSomeData()
{
    var source = from r in records
                 select r;

    DataTable table = ToDataTable(myContext, source);
    return new DataView(table);
}

Vedere soluzione completa qui .

È stato utile?

Soluzione

Si potrebbe passare come dynamic e l'accesso alle proprietà in questo modo:

public void Test(dynamic item)
{
    MessageBox.Show(string.Format("{0} : {1}", item.First_Name, item.Last_Name));
    textBox1.DataBindings.Add("Text", _item, "First_Name");
    textBox2.DataBindings.Add("Text", _item, "Last_Name");
}

Una cosa da considerare è che immobili in tipi anonimi sono di sola lettura, in modo l'utente non sarà in grado di modificare i valori in questo modo. Dal linguaggio C # Spec:

  

I membri di un tipo anonimo sono una sequenza di proprietà di sola lettura inferite dall'oggetto anonima inizializzatore utilizzato per creare un'istanza del tipo.

Si dovrebbe prendere in considerazione dichiarare un tipo per questo invece di utilizzare un tipo anonimo. In questo modo si ottiene anche il vantaggio di intellisense ed essere in grado di rinominare / refactoring le proprietà senza problemi.

Altri suggerimenti

Che tipo di oggetti sono nelle registrazioni? Si dovrebbe essere in grado di lanciare DataGridViewRow.DataBoundItem a qualsiasi tipo di record oggetto contiene.

record diciamo è un elenco di oggetti del cliente. Si dovrebbe essere in grado di andare:

txtFName.Text = ((Customer)DataGridViewRow.DataBoundItem).First_Name;
txtLName.Text = ((Customer)DataGridViewRow.DataBoundItem).Last_Name; 

Se ciò non fosse possibile, allora penso che si dovrà utilizzare la riflessione:

Type type = DataGridViewRow.DataBoundItem.GetType();  
String firstName = (String)type.GetProperty("First_Name")
                        .GetValue(DataGridViewRow.DataBoundItem, null);

Sia kevev22 & deriva avuto l'idea giusta: creare una classe per contenere i dati. Dal momento che posso trasformare un gruppo di risultati IQueryable ad un DataTable, solo senso per farlo:

public DataView GetSomeData()
{
    var source = from r in records
                 select r;

    DataTable table = ToDataTable(myContext, source);
    return new DataView(table);
}

Ora:

myDGView.DataSource = GetSomeData();

E, quando viene selezionata una riga DataGrid, si può lanciare il DataBoundItem a DataRow.

A proposito - per trasformare un gruppo di risultati IQueryable a un DataTable:

public DataTable ToDataTable(DataContext context, IQueryable source)
{
    DataTable table = new DataTable();
    {
        adapter.SelectCommand = context.GetCommand(source);
        sqlCommand.Connection.Open();
        adapter.FillSchema(table, SchemaType.Source);
        adapter.Fill(table);
    }

    return table;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top