大多数WPF / EF教程仅涵盖一个窗口中的数据绑定。但是,实际上数据会在许多窗口中显示。您经常在第一个窗口中显示记录,并在下一个窗口中深入挖掘相关详细信息。
所以,在我的场景中也是如此。在这里你可以看到我的数据结构和ui。实际上我不是在处理客户和发票,但结构是一样的。 (我的具体问题在最后。)
在InvoicesWindow中,我可以选择一个发票并按“显示发票”。这将打开CustomerWindow,显示客户详细信息及其发票。正确的发票已预先选定。对于CustomerWindow中显示的每个发票,我可以添加项目或编辑它们。这是在一个名为“ItemWindow”的分隔窗口中完成的。编辑DataGrids不是一个选项。它们设置为ReadOnly。
这是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
所以,最后我的问题;)
答案 0 :(得分:0)
更清洁的设计是使用MVVM设计模式。
将视图模型注入窗口的上下文,并将视图模型绑定到实体集合或单个实体,将xaml绑定到视图模型中的属性,并使用视图模型中实现的命令进行操作例如添加新的,删除。
窗户不应该知道上下文。
如果您有列表视图模型+窗口和详细信息窗口(最好使用视图模型),则列表视图模型应将所选项目作为上下文传递给详细信息视图模型(或窗口)。
如果窗口没有同时打开或没有相关对象,那么他们的视图模型不应该共享数据库上下文,否则,为了在窗口之间轻松反映更改,他们将不得不共享数据库上下文。