惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
I
InfoQ
Engineering at Meta
Engineering at Meta
D
DataBreaches.Net
L
LangChain Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Recent Announcements
Recent Announcements
GbyAI
GbyAI
爱范儿
爱范儿
Microsoft Security Blog
Microsoft Security Blog
腾讯CDC
美团技术团队
罗磊的独立博客
Microsoft Azure Blog
Microsoft Azure Blog
WordPress大学
WordPress大学
T
The Blog of Author Tim Ferriss
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
雷峰网
雷峰网
M
MIT News - Artificial intelligence
D
Docker
MongoDB | Blog
MongoDB | Blog
F
Fortinet All Blogs
博客园 - 叶小钗

博客园 - guozili

分享12306抢票心得-终极秒杀思路篇 分享12306抢票心得-最终篇 分享12306全自动验证码识别提交,春运抢票准备时 分享“12306 P2P平台”创业Idea 分享12306秒票杀手锏源码 分享12306秒票心得及杀手锏 分享基于EF+MVC+Bootstrap的通用后台管理系统及架构 分享基于EF+WCF的通用三层架构及解析 分享基于silverlight的仿“百度文库”的文档控件 分享基于silverlight的一个“树形结构图”控件 基于 Silverlight的快速开发框架RapidSL新版改进源码 基于 Silverlight的快速开发框架RapidSL之MVVM解析 基于Silverlight的快速开发框架RapidSL之开源 分享基于silverlight的一个大文件上传控件 抢火车票利器:分享一个抓取火车票转让信息的小程序 基于 Silverlight的精简框架之版本升级及使用 基于 Silverlight的精简框架之版本和控件更新 Silverlight project demos for MSRA in 2009,to look forward to silverlight's furture 异步编程练习
基于Silverlight的快速开发框架RapidSL新特性解析
guozili · 2012-08-28 · via 博客园 - guozili

对sl传统的开发方式进行了集成和封装,核心模块基于MVVM,通用的CRUD ViewModel,只需要定制自己的Xaml View,提供了非常便捷的快速开发方式; 采用了Silverlight 5.0 + EF4.1 Code First + Ria Service SP2 + Ria Service Toolkit + Silverlight Control Toolkit + Light MVVM;已经实现了轻量级的权限管理,上传模块,内容管理,作为实例,涉及到了sl开发的各种技术难点和技巧,既可以作为学习,也可以作为项目开发的原型

点击预览 | 源代码

支持动态加载.xap,面向插件开发

  • RapidSL.SL.App.Portal提供主框架的UI逻辑,只需要开发自己的App,如RapidSL.SL.App.Main

     

  • 然后配置菜单:

    1 <sdk:TreeViewItem Header="产品管理" IsExpanded="True">
    2                                 <controls:AdminMenuItem Id="1" Margin="2" Content="ProductEdit" NavigateView="RapidSL.SL.App.Main.xap/Product.Index" ViewPermission="ProductView"/>
    3                                 <controls:AdminMenuItem Id="2" Margin="2" Content="CategoryEdit" NavigateView="RapidSL.SL.App.Main.xap/Category.Index" ViewPermission="CategoryView"/>
    4                             </sdk:TreeViewItem>

    NavigateView="RapidSL.SL.App.Main.xap/Product.Index"将调用XapHost控件从服务端下载动态加载

    NavigateView="RapidSL.SL.App.Portal.Admin"将调用当前程序集的控件

  •  XapHost控件提供动态下载.xap及加载

     1 public XapHost(string xapUri, string viewName = null)
     2         {
     3             InitializeComponent();
     4 
     5             this.FileName = xapUri;
     6 
     7             var xapLoad = new XapLoader(xapUri);
     8             xapLoad.DownloadProgressChanged += (s, e) =>
     9             {
    10                 this.TotalSize = (e.TotalBytesToReceive * 1d / 1024 / 1024).ToString("0.00");
    11                 this.Percentage = e.ProgressPercentage;
    12             };
    13 
    14             xapLoad.LoadCompleted += (s, e) =>
    15             {
    16                 this.Content = e.Element;
    17             };
    18 
    19             xapLoad.LoadControl(null, viewName);
    20         }

对Resource的支持

  • 找到所有标识有 StaticResourceAttribute的类,然后创建相关实例,并注入到Application.Resources,相当于在 App.xaml里手写资源
  • 实现了资源管理器对资源进行注入管理

View Code

 1 public class ViewModelManager
 2     {
 3         private static Application app = Application.Current;
 4 
 5         public static void InjectViewModelsToResources()
 6         {
 7             foreach (AssemblyPart ap in Deployment.Current.Parts)
 8             {
 9                 var sri = Application.GetResourceStream(new Uri(ap.Source, UriKind.Relative));
10                 var assembly = new AssemblyPart().Load(sri.Stream);
11 
12                 InjectViewModelsToResources(assembly);
13             
14             } 
15         }
16 
17         public static void InjectViewModelsToResources(Assembly assembly)
18         {
19             foreach (Type type in assembly.GetTypes())
20             {
21                 var attributes = type.GetCustomAttributes(false);
22 
23                 foreach (var attribute in attributes)
24                 {
25                     if (attribute is StaticResourceAttribute)
26                     {
27                         var resourceKey = ((StaticResourceAttribute)attribute).Key;
28                         if (string.IsNullOrEmpty(resourceKey))
29                             resourceKey = type.Name;
30 
31                         var obj = Activator.CreateInstance(type);
32                         if (!app.Resources.Contains(resourceKey))
33                             app.Resources.Add(resourceKey, obj);
34                     }
35                 }
36             }
37         }
38 
39         public static T GetViewModelFromResources<T>()
40         {
41             var key = typeof(T).Name;
42             if (app.Resources.Contains(key))
43                 return (T)app.Resources[key];
44             else
45                 return default(T);
46         }
47     }

键盘Enter键提交表单

    • 使用AttatchProperty实现传统Html表单的键盘Enter提交

      1 <Grid x:Name="LayoutRoot" core:AttachProperties.SubmitButton="{Binding ElementName=submit}">
      2 <Button x:Name="submit" Content="登录" Margin="20,0,20,0" Padding="20,0,20,0" Command="{Binding UserLogin}"/>
      3 </Grid>

  • 具体绑定按钮和键盘事件

     1 #region SubmitButton AttachProperty
     2         public static object GetSubmitButton(DependencyObject obj)
     3         {
     4             return (object)obj.GetValue(SubmitButtonProperty);
     5         }
     6 
     7         public static void SetSubmitButton(DependencyObject obj, object value)
     8         {
     9             obj.SetValue(SubmitButtonProperty, value);
    10         }
    11 
    12         // Using a DependencyProperty as the backing store for SubmitButton.  This enables animation, styling, binding, etc...
    13         public static readonly DependencyProperty SubmitButtonProperty =
    14             DependencyProperty.RegisterAttached("SubmitButton"typeof(object), typeof(AttachProperties), new PropertyMetadata(SubmitButtonChanged));
    15 
    16         private static void SubmitButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    17         {
    18             var button = (ButtonBase)e.NewValue;
    19             var form = d as UIElement;
    20             form.KeyDown += (s, se) =>
    21             {
    22                 if (se.Key == Key.Enter)
    23                 {
    24                     button.Focus();
    25                     if (button.Command != null)
    26                        button.Dispatcher.BeginInvoke(()=>  button.Command.Execute(null));
    27                 }
    28             };
    29         }
    30         #endregion