大多数 WPF/EF 教程仅在一个窗口中介绍数据绑定。然而,实际上数据会显示在许多窗口中。您经常在第一个窗口中显示一条记录,并在下一个窗口中深入挖掘相关细节。
因此,在我的场景中也是如此。在这里你可以看到我的数据结构和用户界面。实际上我不是在处理客户和发票,但结构是相同的。(我的具体问题在最后。)
在 InvoicesWindow 中,我可以选择发票并按“显示发票”。这将打开一个显示客户详细信息和他的发票的 CustomerWindow。正确的发票是预先选择的。对于 CustomerWindow 中显示的每个发票,我可以添加项目或编辑它们。这是在一个名为“ItemWindow”的单独窗口中完成的。编辑 DataGrids 不是一种选择。它们设置为只读。
这是 wpf-window 类的代码(我只完成了显示数据,没有保存):
发票窗口:
public partial class InvoicesWindow : Window
{
private MyEntities context = new MyEntities();
public InvoicesWindow ()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
CollectionViewSource invoicesViewSource = (CollectionViewSource)FindResource("invoicesViewSource");
invoicesViewSource.Source = context.Invoices;
}
private void ShowInvoice_Click(object sender, RoutedEventArgs e)
{
Invoice selectedInvoice = (Invoice)InvoicesDataGrid.SelectedItem;
var customerWindow = new CustomerWindow(selectedInvoice);
customerWindow.ShowDialog();
}
}
客户窗口:
public partial class CustomerWindow : Window
{
private MyEntities context = new MyEntities();
private Invoice selectedInvoice;
public CustomerWindow()
{
InitializeComponent();
}
public CustomerWindow (Invoice selectedInvoice)
{
InitializeComponent();
this.selectedInvoice = selectedInvoice;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//Set the data
CollectionViewSource customerViewSource = (CollectionViewSource)FindResource("customerViewSource ");
customerViewSource.Source = context.Customers.Where(p => p.id == selectedInvoice.Customer.id);
//Select the right invoice
CollectionViewSource customerInvoicesViewSource = (CollectionViewSource)FindResource("customerInvoicesViewSource ");
customerInvoicesViewSource.Items.MoveCurrentTo(((ObjectSet<Invoice>)customerInvoicesViewSource.Source).Where(p => p.id == selectedInvoice.id).SingleOrDefault());
}
private void EditItem_Click(object sender, RoutedEventArgs e)
{
Item selectedItem = (Item)ItemsDataGrid.SelectedItem;
var itemWindow = new ItemWindow((IQueryable<Customer>)(customerViewSource.Source),selectedInvoice,selectedItem);
itemWindow.ShowDialog();
}
}
物品窗口:
public partial class ItemWindow : Window
{
private Invoice _selectedInvoice;
private Invoice _selectedItem;
private IQueryable<Customer> _customers;
public ItemWindo()
{
InitializeComponent();
}
public ItemWindow(IQueryable<Customer> customers, Invoice selectedInvoice, Item selectedItem)
{
InitializeComponent();
this._customers = customers;
this._selectedInvoice = selectedInvoice;
this._selectedItem = selectedItem;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//Set the data
CollectionViewSource customerViewSource = (CollectionViewSource)FindResource("customerViewSource");
invoicesViewSource.Source = _customers;
//Select the right invoice
CollectionViewSource customerInvoicesViewSource = (CollectionViewSource)FindResource("customerInvoicesViewSource ");
customerInvoicesViewSource.Items.MoveCurrentTo(_selectedInvoice);
//Select the right item
CollectionViewSource customerInvoicesItemsViewSource = (CollectionViewSource)FindResource("customerInvoicesItems");
customerInvoicesItems.Items.MoveCurrentTo(_selectedItem);
}
}
我把代码写出来了。因此,可能缺少一些演员表并且某些方法拼写错误。我希望我用“ObjectSet”得到正确的类型,它也可以是“ObjectCollection”或类似的东西。
XAML 是在 VS2010 的帮助下广泛创建的,如下视频所示:http: //msdn.microsoft.com/de-de/data/ff806174.aspx
所以,最后我的问题;)
- 我应用的装订设计是否正确?
- 在 CustomerWindow 中,我创建了一个新上下文。
- 在 CustomerWindow 和 ItemWindow 之间,我只是传递相同上下文的数据并手动选择当前项目。
- 在CustomerWindow 中,我使用一个ObjectSet(或ObjectCollection,我不再确定类型),其中一个条目作为customersCollectionViewSource 的Source。这工作正常。但是,不需要集合,因为我只编辑一个客户。我没有设法将单个客户设置为来源。我不知道如何调整 VS2010 生成的视图源。
- 我还没有保存。但我认为由于我在 CustomerWindow 和 ItemWindow 之间的设计,我会遇到问题。也许你可以在这里给我一些建议。
- 当 ItemWindow 中的“应用”按钮被按下时,应在 DB 中更新项目数据。但不是下面 CustomerWindow 中与客户和发票相关的数据。
- 关闭 ItemWindow 时,应更新 CustomerWindow 中项目的 DataGrid。但不是 CustomerWindow 中的其余字段,因为这里可能在打开 ItemWindow 之前已更改数据。
- 我克服“同步问题”的唯一解决方案:如果有任何更改,用户必须先在 CustomerWindow 中按“应用”,然后才能按“新项目”或“编辑项目”。(有点像使用两台显示器时 Windows 7 的“窗口分辨率控制”)但这对用户来说不太友好。