Web RSS 生成器 第 3 部分: Silverlight 应用程序
对开源 Web RSS 生成器的描述
引言
Web RSS Builder 是一款用于使用 Web 和 Silverlight 界面管理 RSS 文件的开源应用程序。当您需要使用 Web 应用程序管理服务器上的 RSS 文件时,此应用程序非常有用。
该应用程序托管在 CodePlex 上,网址为 http://WebRSSBuilder.codeplex.com。
这是描述此应用程序的三部分帖子的第三部分
- Web RSS 生成器 第 1 部分:ASP.NET 和 Silverlight 的通用 XML 数据源
- Web RSS 生成器 第 2 部分:ASP.NET 应用程序
- Web RSS 生成器 第 3 部分:
Silverlight 应用程序
Silverlight 应用程序
Silverlight 式思考!
在使用 Silverlight 时,您必须以不同于典型 Web 开发的方式思考,现在您拥有一个客户端和一个服务器,它们可以通过某种方式连接(使用 Web 服务或其他任何方式)。如果您不熟悉 Silverlight,我建议您先阅读相关内容,因为本文无意解释 Silverlight 是什么。通常,当您阅读或观看有关 Silverlight 中数据绑定的视频时,示例将绑定到数据库或绑定到 Entity Framework 对象。至于其他数据源,例如 XML 文件,我没有遇到任何标准的或现成的技术可以直接使用。因此,我一直在探索绑定 XML 文件的不同方法,我将讨论选项、我的选择以及最重要的是我为什么选择它。
MVC 和 MVVM 有什么区别?
随着 WPF 和 Silverlight 中引入 XAML,Microsoft 旨在区分视图(即如何呈现数据)与任何其他可能需要的逻辑或过程,以增加应用程序的解耦并提高可重用性,您的视图应始终关注如何呈现数据,仅此而已。
但这在 MVC 中是视图的工作,所以有什么区别?
区别在于,您的模型中呈现的数据始终依赖于某个数据源,无论是数据库中的表、XML 架构还是其他内容。但是,这些数据可以从不同的角度查看。您可以有一个名为 Customer 的模型,然后您需要根据不同的位置、销售或订单等来查看该客户。要做到这一点,您之前不得不编写一些代码在视图中根据您的偏好进行过滤。
在 MVVM 中,您可以简单地定义一个 ViewModel 来根据您的选择过滤数据,而视图不必处理。
这是 MVVM 与 MVC 不同的原因之一,另一个原因是它本身的技术导致了 MVVM,如果您比较传统的 ASP 或 Windows 窗体绑定和事件处理程序,几乎不可能有一个 Windows 窗体或 ASP.NET 页面而没有代码隐藏中的任何代码。
您可能会问,我为什么首先需要这样做?
嗯,答案很简单,因为它是 WEB PAGE,它是 WINDOWS FORM,它是视图。它不是您应用程序的逻辑。那您为什么要这样做呢?您只是在查看数据?为什么视图不能有一种技术来插入任何您想要提供的功能,例如,点击客户时。因此,这里引入了 Command 和 Data Context 的整个概念,以便 XAML 为 MVVM 提供支持。

用于 XML 数据服务的 MVVM 模式:WCF 还是 Domain Data Services?
我们将使用核心组件通过 MVVM 模式为 Silverlight 应用程序提供数据。首先,让我们探讨将数据绑定到 Silverlight 应用程序的不同方法
- 使用 Domain Data Services:它需要 Entity Framework
- 使用 WCF Data Service:它需要 Entity Framework 或实现
IQuerable
的对象 - 使用 WCF Web 服务
- 实现您自己的连接器:例如套接字或其他东西
第一种选择不适合我们,因为我们没有 Entity Framework 数据源。第四种工作量太大(重复造轮子)。我在实现 IQuerable
数据源或使用简单的 WCF Web 服务之间做出了选择,我选择了后者。这似乎工作量较小。
WCF Web 服务
WCF Web 服务实际上很简单,只是封装了控制器 RSSFeedXLinqController
来加载或保存特定文件。
[OperationContract]
public RSSFeed GetRssFeed(int FileID)
{
DomainServiceDB d = new DomainServiceDB();
File f = d.GetFileByID(FileID);
if (HttpContext.Current.User.Identity.IsAuthenticated)
if (HttpContext.Current.User.IsInRole(f.aspnet_Roles.RoleName))
return new RSSFeedXLinqController().LoadRss(f.FileURL);
else
throw new Exception("Access Denied");
return null;
}
ViewModel
RSSViewModel
实现 INotifyPropertyChanged
以通知视图控件数据中的任何更改。RssViewModel
包含一个 Feed 对象(我们的 Model)、一个 Load Command 和 Save Command,以及一个用于 RSSItem
的 PagedCollectionView
,我使用此对象来实现分页。
public class RSSViewModel: INotifyPropertyChanged
{
private RSSFeed feed;
private bool isChanged;
public bool IsChanged {..}
WCFRSSDataSourceClient client;
public DelegateCommand LoadCommand {get; set;}
private PagedCollectionView itemsPaged;
public PagedCollectionView ItemsPaged {....}
public DelegateCommand SaveCommand { get; set; }
public RSSFeed Feed {..}
public event PropertyChangedEventHandler PropertyChanged;
...
此类中的主要方法是加载和保存文件,这只是建立与 Web 服务的连接。
private void LoadRSS(object Parameter)
{
client = new WCFRSSDataSourceClient("CustomBinding_WCFRSSDataSource1");
client.GetRssFeedCompleted += new EventHandler(client_GetRssFeedCompleted);
client.GetRssFeedAsync(((File)App.Current.Resources["File"]).FileID);
}
public void SaveRSS(object Parameter)
{
client = new WCFRSSDataSourceClient("CustomBinding_WCFRSSDataSource1");
client.UpdateRssFeedCompleted +=new EventHandler client_UpdateRssFeedCompleted);
client.UpdateRssFeedAsync(feed, ((File)App.Current.Resources["File"]).FileID);
...
Domain Data Service 对 MVVM 友好吗?
至于其他管理页面,例如管理文件和管理角色,我使用了 Domain Data Services 来绑定到数据源。
嗯,人们可以争论 Domain Data Service 是否对 MVVM 友好?以及我们是否应该为 Domain Data Service 实现 ViewModel
?我个人认为,这取决于;如果您要按原样查看模型,则无需仅为了模拟模型和建立连接而创建 ViewModel
,因为已实现嵌入式机制来在 XAML 中声明 Domain Data Source,因此由于模式是为了让我们的生活更轻松,像 Manage Roles 和 Manage Files 这样的页面将没有任何 ViewModel
,您仍然可以打开代码隐藏并看到它仍然是空的。所以我仍然遵循无代码视图的概念。但是,在其他情况下,例如主页案例,我需要根据登录的用户查看文件,我为 Domain Service 创建了一个 ViewModel
来过滤用户。
在数据表单中使用组合框:问题与解决方案
在使用绑定到 Domain Data Service 的数据表单中的组合框时,我遇到一个值得提及的问题。出于某种原因,当用户更改组合框时,此组合框的键值不会改变。在我找到解决方案之前,我花了将近 4 个小时寻找。要在 Data Form 中绑定组合框
< combobox name="combobox2" itemssource="{Binding Source={StaticResource RoleSource},
Path=Data, Mode=OneWay}" selecteditem="{Binding Path=RoleID, Mode=TwoWay,
Converter={StaticResource RoleConverter}, NotifyOnValidationError=True,
ValidatesOnExceptions=True}" displaymemberpath="RoleName"
selectedvaluepath="RoleId" />
- Items Source 应绑定到包含 Key 和 Value 的数据源,并使用单向绑定模式。
- Display Member Path 应包含值字段名。
- Selected Value Path 应包含键值字段。
- 最重要的是,您应该定义一个转换器,它将获取 Key(在我看来是 Item ID)并返回项对象,反之亦然。
结论
我希望这个应用程序对需要它的人有所帮助。非常感谢您提供反馈,使这个应用程序更好,并讨论这些帖子中涉及的概念。
你喜欢这篇文章吗?
如果你喜欢,请投票支持它。:)