从datagrid C#Entity Framework WPF获取数据

时间:2022-06-14 09:51:53

I've a datagrid in WPF, I autogenerate the columns and rows from an sql data entity.

我在WPF中有一个数据网格,我从一个sql数据实体自动生成列和行。

I've tried several different ways but unable to get a specific column or row data,

我尝试了几种不同的方法,但无法获得特定的列或行数据,

for eg: When the user selects a row, I'd like to be able to get a single cell's data and use it in my LINQ query.

例如:当用户选择一行时,我希望能够获取单个单元格的数据并在我的LINQ查询中使用它。

Please let me know if you have any questions.

请让我知道,如果你有任何问题。

Thanks

谢谢

1 个解决方案

#1


0  

You have to cast the selected row as an item of the same type as your data class.

您必须将所选行强制转换为与数据类相同类型的项。

Example:

例:

Drop a data grid on your form. call it 'grdMyData', drop a button on your form call it 'btnGetData'

删除表单上的数据网格。称之为'grdMyData',在表单上放一个按钮称为'btnGetData'

Create a class in your application to hold your data, in my case:

在我的情况下,在您的应用程序中创建一个类来保存您的数据:

    public class channel
    {
      public int id { get; set; }
      public string channelName { get; set; }
    }

Create your self a list of test data (Note this could just as easy come from an entity model, I'm just using this for illustration.)

创建一个测试数据列表(请注意,这可能很容易来自实体模型,我只是用它来说明。)

    public List<channel> testData = new List<channel>
    {
      new channel {id = 1, channelName = "BBC1"},
      new channel {id = 2, channelName = "BBC2"},
      new channel {id = 3, channelName = "ITV1"},
      new channel {id = 4, channelName = "Channel 4"},
      new channel {id = 5, channelName = "Channel 5"}
    };

In your button click handler, bind your data to your grid...

在按钮单击处理程序中,将数据绑定到网格...

    grdMyData.AutoGenerateColumns = true;
    grdMyData.ItemsSource = testData;

In your grid 'SelectionChanged' event add the following:

在您的网格'SelectionChanged'事件中添加以下内容:

    if (grdMyData.SelectedIndex != -1)
    {
      channel selecteditem = (channel) grdMyData.Items[grdMyData.SelectedIndex];
      MessageBox.Show(selecteditem.channelName);
    }

You use 'SelectedIndex' to find the row that was clicked, and use that as an index into the Items array. You then cast that item as an object of your class type, and access the properties as normal.

使用'SelectedIndex'查找单击的行,并将其用作Items数组的索引。然后,您将该项目转换为类类型的对象,并正常访问属性。

The -1 check is needed so that it doesn't fire when drawing / filling the grid, if no actual rows are clicked the index will always be -1.

需要-1检查,以便在绘制/填充网格时不会触发,如果没有单击实际行,则索引将始终为-1。

UPDATE

It seems that the OP is a little confused as to the way objects are used here, so based on the comments I'm going to attempt to clear things up a little:

看来OP对于这里使用对象的方式有点困惑,所以根据评论,我将尝试清理一点:

Where I use "channel" above that's what I've named my object that holds the data I'm populating the grid with, for other purposes this will be an object that is specific to that purpose, EG: if your showing a list of users you may have a "user" object like so:

我在上面使用“channel”的地方就是我命名的对象,它保存了我正在填充网格的数据,为了其他目的,这将是一个特定于此目的的对象,EG:如果你显示一个列表用户可能有一个“用户”对象,如下所示:

    public class user
    {
      public string firstName { get; set; }
      public string lastName { get; set; }
      public int age { get; set; }
    }

If you where then to get a row of data from your data grid, rather than:

如果您从那里获取数据网格中的一行数据,而不是:

      channel selecteditem = (channel) grdMyData.Items[grdMyData.SelectedIndex];

you would use:

你会用:

      user selecteditem = (user) grdMyData.Items[grdMyData.SelectedIndex];

populating the grid in the first place would be similar, but instead of a list of channels, created statically as my example shows (Which was just for demo purposes) you might get that from a database:

首先填充网格将是类似的,但不是通道列表,而是静态创建,如我的示例所示(这只是为了演示目的),您可以从数据库中获取:

    var myUsers = from p in mydb.userstable
                  select p;

    grdMyData.ItemSource = myUssers;

The important thing to remember is that what ever you put into the datagrid has a direct one-to-one mapping to the row you pull out when using the selected data.

需要记住的重要一点是,您在数据网格中放置的内容与使用所选数据时拉出的行具有直接的一对一映射关系。

In reality, rather than pull directly from your database as I've just done, you may be more likely to loop over that collection and put custom objects into your own object collection, because if your creating everything automatically then you've chance not to know the layout of the object, and may even have other items in there that you don't want to display.

实际上,不像我刚刚完成的那样直接从数据库中提取,您可能更有可能遍历该集合并将自定义对象放入您自己的对象集合中,因为如果您自动创建所有内容,那么您有可能不会知道对象的布局,甚至可能有其他你不想显示的项目。

since you mentioned you have only selected items in your grid then I can assume that your filtering only those out from your database retrieval, so it's probably better if you create a class to model just those items, then populate a list of those classes, and give that list to the datagrid.

既然你提到你只选择了网格中的项目,那么我可以假设你只过滤了数据库检索中的项目,所以如果你创建一个类来模拟这些项目,然后填充这些类的列表,那么可能会更好。将该列表提供给datagrid。

Then use your own custom class in place of channel/user/whatever in the examples above.

然后使用您自己的自定义类代替上面示例中的频道/用户/任何内容。

#1


0  

You have to cast the selected row as an item of the same type as your data class.

您必须将所选行强制转换为与数据类相同类型的项。

Example:

例:

Drop a data grid on your form. call it 'grdMyData', drop a button on your form call it 'btnGetData'

删除表单上的数据网格。称之为'grdMyData',在表单上放一个按钮称为'btnGetData'

Create a class in your application to hold your data, in my case:

在我的情况下,在您的应用程序中创建一个类来保存您的数据:

    public class channel
    {
      public int id { get; set; }
      public string channelName { get; set; }
    }

Create your self a list of test data (Note this could just as easy come from an entity model, I'm just using this for illustration.)

创建一个测试数据列表(请注意,这可能很容易来自实体模型,我只是用它来说明。)

    public List<channel> testData = new List<channel>
    {
      new channel {id = 1, channelName = "BBC1"},
      new channel {id = 2, channelName = "BBC2"},
      new channel {id = 3, channelName = "ITV1"},
      new channel {id = 4, channelName = "Channel 4"},
      new channel {id = 5, channelName = "Channel 5"}
    };

In your button click handler, bind your data to your grid...

在按钮单击处理程序中,将数据绑定到网格...

    grdMyData.AutoGenerateColumns = true;
    grdMyData.ItemsSource = testData;

In your grid 'SelectionChanged' event add the following:

在您的网格'SelectionChanged'事件中添加以下内容:

    if (grdMyData.SelectedIndex != -1)
    {
      channel selecteditem = (channel) grdMyData.Items[grdMyData.SelectedIndex];
      MessageBox.Show(selecteditem.channelName);
    }

You use 'SelectedIndex' to find the row that was clicked, and use that as an index into the Items array. You then cast that item as an object of your class type, and access the properties as normal.

使用'SelectedIndex'查找单击的行,并将其用作Items数组的索引。然后,您将该项目转换为类类型的对象,并正常访问属性。

The -1 check is needed so that it doesn't fire when drawing / filling the grid, if no actual rows are clicked the index will always be -1.

需要-1检查,以便在绘制/填充网格时不会触发,如果没有单击实际行,则索引将始终为-1。

UPDATE

It seems that the OP is a little confused as to the way objects are used here, so based on the comments I'm going to attempt to clear things up a little:

看来OP对于这里使用对象的方式有点困惑,所以根据评论,我将尝试清理一点:

Where I use "channel" above that's what I've named my object that holds the data I'm populating the grid with, for other purposes this will be an object that is specific to that purpose, EG: if your showing a list of users you may have a "user" object like so:

我在上面使用“channel”的地方就是我命名的对象,它保存了我正在填充网格的数据,为了其他目的,这将是一个特定于此目的的对象,EG:如果你显示一个列表用户可能有一个“用户”对象,如下所示:

    public class user
    {
      public string firstName { get; set; }
      public string lastName { get; set; }
      public int age { get; set; }
    }

If you where then to get a row of data from your data grid, rather than:

如果您从那里获取数据网格中的一行数据,而不是:

      channel selecteditem = (channel) grdMyData.Items[grdMyData.SelectedIndex];

you would use:

你会用:

      user selecteditem = (user) grdMyData.Items[grdMyData.SelectedIndex];

populating the grid in the first place would be similar, but instead of a list of channels, created statically as my example shows (Which was just for demo purposes) you might get that from a database:

首先填充网格将是类似的,但不是通道列表,而是静态创建,如我的示例所示(这只是为了演示目的),您可以从数据库中获取:

    var myUsers = from p in mydb.userstable
                  select p;

    grdMyData.ItemSource = myUssers;

The important thing to remember is that what ever you put into the datagrid has a direct one-to-one mapping to the row you pull out when using the selected data.

需要记住的重要一点是,您在数据网格中放置的内容与使用所选数据时拉出的行具有直接的一对一映射关系。

In reality, rather than pull directly from your database as I've just done, you may be more likely to loop over that collection and put custom objects into your own object collection, because if your creating everything automatically then you've chance not to know the layout of the object, and may even have other items in there that you don't want to display.

实际上,不像我刚刚完成的那样直接从数据库中提取,您可能更有可能遍历该集合并将自定义对象放入您自己的对象集合中,因为如果您自动创建所有内容,那么您有可能不会知道对象的布局,甚至可能有其他你不想显示的项目。

since you mentioned you have only selected items in your grid then I can assume that your filtering only those out from your database retrieval, so it's probably better if you create a class to model just those items, then populate a list of those classes, and give that list to the datagrid.

既然你提到你只选择了网格中的项目,那么我可以假设你只过滤了数据库检索中的项目,所以如果你创建一个类来模拟这些项目,然后填充这些类的列表,那么可能会更好。将该列表提供给datagrid。

Then use your own custom class in place of channel/user/whatever in the examples above.

然后使用您自己的自定义类代替上面示例中的频道/用户/任何内容。