65.9K
CodeProject 正在变化。 阅读更多。
Home

AdventureWorks.WPF (第一部分)

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.77/5 (22投票s)

2008年4月4日

CPOL

8分钟阅读

viewsIcon

106148

downloadIcon

2688

我创建实际业务应用程序的旅程

背景

WPF 准备好应对真实世界的挑战了吗?答案是肯定的!那么,证明它吧!

接下来的几篇文章将是我使用 WPF 编写一个真实商业应用程序的文档记录!需要注意的是,我只使用了 WPF 提供的功能,而没有其他任何东西!!!第一部分将为未来的文章奠定基础。

为什么要写这篇文章,难道已经讲过了吗?

可能吧,但有什么比动手玩耍更好的学习方式呢?更严肃地说,我看到的唯一一个真正的参考应用程序是 DinnerNow 应用程序。 DinnerNow 是一个完美利用 .NET 3.0 所有功能的示例,但它有点过于复杂。这些文章的目的是介绍一些可以用来创建类似 DinnerNow 的应用程序的基础知识!!!

免责声明

这是一篇入门文章,但它假设您对 WPF、SQL Server、MVC 和 LINQ 有一定的了解。

WPF 简介

高级 WPF

MVC

LINQ/SQL Server

WPF 训练营

大多数 LOB 应用程序都消耗和操作数据... 因此,让我们从那里开始!

开始之前...

好的,这很明显,但请使用 Visual Studio 2008 创建一个新的 WPF 应用程序项目!

Data

可以安全地假设 Microsoft SQL Server 是一个流行的数据源。下载 AdventureworksLT SQL 数据库并进行安装。

创建 LINQ-to-SQL 映射

向项目添加一个新项,使用“LINQ to SQL Classes”模板。

打开服务器资源管理器并添加一个数据连接。输入您的服务器名称,然后选择 AdventureWorksLT 作为数据库。

添加后,选择所有表并将它们拖到设计表面。这将创建所有必需的实体(我们的模型)。

模型-视图-控制器?

我将松散地遵循 Josh 对 MVC 模式的实现,我的可能更像 Dr. WPFMV-poo

模型

应用程序运行所依赖的信息的特定领域表示。

免责声明

我不是软件架构师,本文也不是关于如何构建 nTier 或 MVC 应用程序的设计指南。

虽然这是我追求创建真实 LOB 应用程序的历程... 但目前,我将稍微作弊一下。我将使用 LINQ 返回的数据集作为我的模型。这种方法的好处是它已经实现了 INotifyPropertyChanged 事件!在所有真正的架构师开始抨击我之前,未来的文章将解决这个问题。

为了不过多透露,未来的计划是拥有一个 SQL DB -> LINQ-to-SQL -> WCF 服务 -> 模型。

模型的主要目的是以易于绑定的格式表示数据!

关于代码

如果您运行提供的示例代码,请记住更改设置文件中的连接字符串。它目前使用此连接字符串

Data Source=
    localhost\sqlexpress;Initial Catalog=AdventureWorksLT;Integrated Security=True

视图

将模型渲染成适合交互的形式。这正是 WPF 发挥作用的地方... 我正在创建各种用户控件并将它们绑定到我的窗口内容!

视图和模型之间的通信通过数据绑定和路由命令(通过控制器)进行。

每个视图都将加载到一个新窗口中。我将使用 这些 附加属性来跟踪我打开的窗口。

local:WindowViewState.IsManaged="True"

销售订单

SalesOrderView

好了,我没有 Grant Hinkson 在我的口袋里... 它不漂亮,但它很实用!!!

此视图的目的是允许用户查看/编辑任何现有销售订单。订单日期、截止日期、发货日期、发货方式等数据都可以更改。要更改客户详细信息,将使用一个单独的视图。每个客户都有一个关联的地址列表,收货地址和账单地址只能更改为列表中已有的有效地址。

还将支持以下命令:新建、删除和更新(将在后续文章中实现)。

销售订单视图数据绑定到 SalesOrderHeaders 集合。

Customers

CustomersView

此视图用于查看/编辑客户。姓名、中间名、姓氏等详细信息都可以更改。

客户视图数据绑定到 Customers 集合。

产品

ProductsView

此视图用于查看/编辑产品。名称、零件号、标价等详细信息都可以更改。

产品视图数据绑定到 Products 集合。

控制器 (又名 Poo)

处理响应事件,通常是用户操作,并可能对模型进行更改。控制器基本上是将模型和视图粘合在一起的胶水。

控制器用于与模型交互(例如,添加新销售订单、删除销售订单、更新销售订单)。

我为视图可以执行的每个操作创建了一些路由命令。有关路由命令的更多信息,请阅读 Josh Smith 发表的 这篇文章

绑定问题 1 (共 n 部分)

本文主要关注数据绑定。在我们深入之前,请阅读 这篇文章,了解我学到的关于绑定的知识... 这些文章将大量使用它!!!

绑定到规范化数据库

AdventureWorksLT 为例。每个客户都有一个地址列表。每个销售订单都有一个客户。如果我现在想创建一个销售订单的数据录入屏幕,我该如何正确绑定它,以便我可以更改交货/账单地址,但仍然将我的选项限制在可用地址内?

<ComboBox ItemsSource="
    {Binding Path=Customer.CustomerAddresses, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
     SelectedValue="{Binding Path=ShipToAddressID}" SelectedValuePath="AddressID" />

ComboBox 非常适合此场景,我首先将 ComboBox.ItemsSource 绑定到所有可用地址(由 Customer 限制)。现在需要做的就是告诉 ComboBox 当前应该选择哪个项目。SelectedValuePath 确定应该使用哪个属性来“标识”当前项目,然后将 SelectedValue 绑定...

仔细检查... ComboBox 绑定到 Customer.CustomerAddresses ,但 SelectedValue 实际上使用的是视觉树上方的绑定源!

这是规范化数据库中一个非常常见的场景...

BindingMode.TwoWay

默认绑定模式并非所有控件都相同。显式设置绑定模式始终是安全的做法。在此场景中,我们将大部分时间使用 BindingMode.TwoWay 。我们希望绑定自动更新我们的模型!

Mode=TwoWay

主/明细绑定

一个常见的场景是主/明细绑定... 如果以销售订单为例... 我将一个 ComboBox 绑定到一系列未关闭的销售订单(Master),一旦选择了销售订单,其详细信息将在详细信息窗格(Detail)中显示。

有两种常见的方法可以做到这一点

将详细信息窗格的 DataContext 绑定到 ComboBox.SelectedItem

DataContext="{Binding Path=SelectedItem, ElementName=SalesOrdersListBox}"

或者使用 {Binding Path=/} 语法。

要使用此绑定,首先设置 IsSynchronizedWithCurrentItem="True" ,然后像这样绑定 DataContext

DataContext="{Binding Path=/}"

UpdateSourceTrigger.Explicit

我想控制数据源何时更新。稍后将详细介绍。

UpdateSourceTrigger=Explicit

WPF 缺少什么(目前)

我确定当时时间是唯一的限制,但 WPF 急需两个控件才能进入 LOB 市场...

日期选择器

这里我使用了 MarlonAvalonControlsLibrary。(它是免费的,并且提供了完整的源代码。)

DataGrid

目前我只使用了一个 ListView,但很快我将升级到 Xceed DataGrid。(它是免费的。)

未来将要解决的问题

  • 控制器和路由命令(提供新建、删除和更新)
  • 验证
  • 迁移到数据服务模型并跨越机器边界

第一部分就到这里了... 如果您觉得这有帮助,请为您喜欢的文章投票... 任何评论(好坏皆可)都非常欢迎!

网站

© . All rights reserved.