WPF XAML - 将数据网格列绑定到外键(数据集)

Posted

技术标签:

【中文标题】WPF XAML - 将数据网格列绑定到外键(数据集)【英文标题】:WPF XAML - Bind datagrid column to foreign key (Dataset) 【发布时间】:2013-10-09 20:57:58 【问题描述】:

我正在开发一个与 Access 2000 数据库对话的简单 WPF 应用程序。我过去使用过实体框架,但似乎我受限于 Access 数据库。我设法生成了一个 DataSet xsd 文件,其中包含每个表的映射以及表之间的关系。架构如下图:

为了将数据绑定到 WPF 数据网格,在从各种表适配器填充数据后,我将 DataContext 设置为 DataSet。我在后面的 WPF 代码中使用以下 C# 来实现这一点:

public partial class MainWindow : Window
   
    private TillDataSet ds = new TillDataSet();
    private TransactionTableAdapter transactionDa = new TransactionTableAdapter();
    private DentistTableAdapter dentistDa = new DentistTableAdapter();
    private Transaction_TypeTableAdapter transactionTypeDa = new Transaction_TypeTableAdapter();
    private Payment_MethodTableAdapter paymentMethodDa = new Payment_MethodTableAdapter();

    public MainWindow()
    
        InitializeComponent();
    

    private void fillDataAdapters()
    
        transactionDa.Fill(ds.Transaction);
        dentistDa.Fill(ds.Dentist);
        transactionTypeDa.Fill(ds.Transaction_Type);
        paymentMethodDa.Fill(ds.Payment_Method);
    

    private void Window_Loaded(object sender, RoutedEventArgs e)
    
        fillDataAdapters();
        this.DataContext = ds;
    

我想显示一个 WPF 数据网格,其中包含来自事务表的详细信息。我能够从事务表中检索基本详细信息。我想要实现的是能够导航表具有的关系,这样我就可以显示牙医名称,而不是外键值。我尝试了以下 XAML:

<!--Transaction List-->
<DataGrid Grid.Row="1" Grid.Column="1" Name="dtgTransactions" AutoGenerateColumns="False" IsReadOnly="True" Margin="10" ItemsSource="Binding Transaction">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Date" Binding="Binding Trans_Date" />
        <DataGridTextColumn Header="Type" Binding="Binding Type" />
        <DataGridTextColumn Header="Dentist" Binding="Binding Dentist.Dentist_Name"/>
        <DataGridTextColumn Header="Payment Method" Binding="Binding Method" />
    </DataGrid.Columns>
</DataGrid>

请注意牙医列下的绑定。当我尝试这个时,我得到一个空的数据列。如何使用 XAML 导航关系?

【问题讨论】:

我没有任何查询,数据直接来自DataContext。 MS Access 交互是通过 OLEDB 进行的,它没有实体框架提供程序。否则我可以形成 LINQ 查询并包含导航属性。我确实在寻找某种加载选项设置,但没有走多远。 尝试添加数据集关系,可能是这样的: ds.Relations.Add("TransactionsDentists", ds.Tables["Transaction"].Columns["DentistID"], ds.Tables["牙医"].Columns["牙医ID"]) 感谢您的建议。我尝试添加关系,但有一个例外,即孩子和父母之间已经存在关系。这至少表明关系已经到位。我确实发现我可以在后面的代码中导航关系。我可以执行以下操作: MessageBox.Show(ds.Transaction.First().DentistRow.Dentist_Name);如果我尝试从 XAML 导航 DentistRow 属性,它仍然会失败...... 是否有绑定错误,进入Debug -> Windows -> Output 【参考方案1】:

这是一个完整的工作示例。请编辑此内容,以便我们查看问题所在。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel Orientation="Vertical" Loaded="StackPanel_Loaded" >
        <DataGrid Grid.Row="1" Grid.Column="1" Name="dtgTransactions" AutoGenerateColumns="False" IsReadOnly="True" Margin="10" ItemsSource="Binding Transaction">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Date" Binding="Binding Trans_Date" />
                <DataGridTextColumn Header="Type" Binding="Binding Type" />
                <DataGridTemplateColumn Header="Dentist">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ItemsControl ItemsSource="Binding Dentists">
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock Text="Binding Dentist_Name"/>
                                        </StackPanel>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </StackPanel>
</Window>
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace WpfApplication1
    
      public class ViewModel
      
        public Transactions Transaction  get; set; 

        public ViewModel()
        
          Transaction = new Transactions();

          Transaction transData = new Transaction();
          transData.ID = 0;
          transData.Trans_Date = DateTime.Now;
          transData.Type = "Type1";

          Dentist dentistData = new Dentist();
          dentistData.ID = 0;
          dentistData.Dentist_Name = "Dentist1 Name";
          transData.Dentists.Add(dentistData);

          Transaction.Add(transData);

          transData = new Transaction();
          transData.ID = 1;
          transData.Trans_Date = DateTime.Now;
          transData.Type = "Type2";

          dentistData = new Dentist();
          dentistData.ID = 1;
          dentistData.Dentist_Name = "Dentist2 Name";
          transData.Dentists.Add(dentistData);

          dentistData = new Dentist();
          dentistData.ID = 2;
          dentistData.Dentist_Name = "Dentist3 Name";
          transData.Dentists.Add(dentistData);


          Transaction.Add(transData);
        
      


      public class Transactions : ObservableCollection<Transaction>
      
        public ObservableCollection<Transaction> TransactionList  get; set; 

        public Transactions()
        
          TransactionList = new ObservableCollection<Transaction>();
        
      


      public class Transaction
      
        public ObservableCollection<Dentist> Dentists  get; set; 
        public int ID  get; set; 
        public DateTime Trans_Date  get; set; 
        public string Type  get; set; 

        public Transaction()
        
          Dentists = new ObservableCollection<Dentist>();
        

      


      public class Dentist
      
        public int ID  get; set; 
        public string Dentist_Name  get; set; 
      

    

【讨论】:

哦,这看起来很有希望。不幸的是,同样的结果......只是显示一个空值:(感谢您的尝试 你能粘贴你所有的类事务吗,牙医。谢谢【参考方案2】:

您的桌子有牙医名称,并且您正在与牙医s

绑定

不管怎样,试试这个;

<ItemsControl ItemsSource="Binding Path=DataContext.Dentist,
 RelativeSource=RelativeSource AncestorType=x:Type Window">

和;

<TextBlock Text="Binding Dentist_Name"/>

【讨论】:

您是在回答问题还是其他答案? 第一个问题。

以上是关于WPF XAML - 将数据网格列绑定到外键(数据集)的主要内容,如果未能解决你的问题,请参考以下文章

在 WPF 中,如何将数据网格列绑定到数据表的特定列?

如何基于二维数组填充 WPF 网格

WPF 绑定

WPF 数据网格绑定工具提示在表格内容绑定刷新时闪烁

如何在C#中将列表与WPF数据网格绑定?

XAML 绑定到 CompositeCollection