【问题标题】:WPF Linq Binding join-qry to DataGridWPF Linq 将连接查询绑定到 DataGrid
【发布时间】:2012-05-25 02:39:03
【问题描述】:

我有以下疑问:

var qry = from itemA in db.TableA 
          join itemB in db.TableB on itemA.ID equals itemB.ID  
          join itemC in db.ItemC on itemA.ID equals itemC.ID  
          select new { itemC, itemA, itemB};

如果我现在像这样将查询绑定到 Datagrid:

dgTest.ItemsSource = qry;

并像这样配置 Datagrid 的 TextColumn:

<DataGrid x:Name="dgTest" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Test" Binding="{Binding TableA.Name}"/>
    </DataGrid.Columns>
</DataGrid>

该列是空的...
谁能告诉我我做错了什么?

提前致谢!

【问题讨论】:

  • 如何设置DataGrid 的DataContext? TableA 是您的 DataContext 的属性吗?您用作数据上下文的对象是否实现了INotifyPropertyChanged?
  • 对不起。忘了提那个。问题已更新。

标签: c# wpf linq binding datagrid


【解决方案1】:

您不能为数据绑定使用隐式类型变量。

假设您的对象TableA、TableB 和TableC 如下所示:

public class TableA
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public class TableB
{
    public int ID { get; set; }
}

public class TableC
{
    public int ID { get; set; }
}

现在您需要创建一个具体的类,而不是像在 select new { 语句中那样使用隐式类型。

例如:

public class MyConcreteClass
{
    public TableA TableA { get; set; }
    public TableB TableB { get; set; }
    public TableC TableC { get; set; }
}

最后,您有 LINQ 查询的类应该如下所示:

public class MyDataSource : INotifyPropertyChanged
{
    private Database db;

    public MyDataSource()
    {
        db = new Database()
        {
            TableA = new List<TableA> 
            {
                new TableA { ID = 1, Name = "Hello world!" }
            },
            TableB = new List<TableB>
            {
                new TableB { ID = 1 }
            },
            TableC = new List<TableC>
            {
                new TableC { ID = 1 },
                new TableC { ID = 2 }
            }
        };
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public IEnumerable<MyConcreteClass> MyConcreteClass
    {
        get { return this.MyQuery(); }
    }

    private IEnumerable<MyConcreteClass> MyQuery()
    {
        var qry = from itemA in db.TableA
                  join itemB in db.TableB on itemA.ID equals itemB.ID
                  join itemC in db.TableC on itemA.ID equals itemC.ID
                  select new MyConcreteClass
                  {
                      TableA = itemA,
                      TableB = itemB,
                      TableC = itemC
                  };

        return qry.AsEnumerable();
    }
}

Database 类正在寻找类似的东西:

public class Database
{
    public IEnumerable<TableA> TableA { get; set; }
    public IEnumerable<TableB> TableB { get; set;  }
    public IEnumerable<TableC> TableC { get; set;  }
}

并将DataGrid 的ItemsSource 属性设置为{Binding MyConcreteClass}。

最重要的几点是:

  • 您只能绑定到一个属性。您不能将数据绑定到字段或方法。
  • 您不能绑定到隐式类型。

如果需要,不要忘记让您的视图模型实现 INotifyPropertyChanged,并在需要时使用 ObservableCollections。

【讨论】:

  • 问题是:我正在使用 LinqToEntities 并且类已经由 Linq 创建。我需要加入 qry 才能将 3 个表的列添加到一个数据网格中...
  • 您是否在数据库中创建一个包含您需要的列信息的视图并将其添加到您的实体中,就像一个表一样。或者您需要创建一个像MyConcreteClass 这样的自定义对象并处理对此对象的更改以将它们反映到您的实体中。我的回答只是一个一般性的答案,您需要根据您的代码进行调整。请记住,您不能绑定到隐式类型。
  • 创建了一个包含 Linq 创建的 3 个类的类。奇迹般有效!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 2017-10-13
  • 2011-12-17
  • 1970-01-01
  • 1970-01-01
  • 2013-07-28
  • 1970-01-01
相关资源
最近更新 更多