【问题标题】:WPF XAML - Bind datagrid column to foreign key (Dataset)WPF XAML - 将数据网格列绑定到外键(数据集)
【发布时间】: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

标签: c# wpf xaml ms-access datagrid


【解决方案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}"/>

【讨论】:

  • 您是在回答问题还是其他答案?
  • 第一个问题。
猜你喜欢
  • 1970-01-01
  • 2011-08-15
  • 1970-01-01
  • 2021-01-27
  • 2014-07-30
  • 2011-01-31
  • 2013-04-15
  • 2011-01-31
  • 2017-05-14
相关资源
最近更新 更多