基于Silverlight的快速开发框架RapidSL新特性解析
支持动态加载.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 }
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