zoukankan      html  css  js  c++  java
  • silverlight所有


    2009年04月23日 星期四 23:25

    2008年10月,写了一篇《动态加载XAML文件》,其中按照Silverlight MSDN的“资源文件”一节的介绍,按照“Build Action”(生成操作)的三种不同方式Resource、Content、None,分别加载了三个XAML文件,以示不同。

    这两天经过实践,发现并不像文档中说的“Build Action”仅能取三者之一,比如俺博客中也提到了默认的“Page”也可以,和“Resource”基本上一样。重要的是,这两天发现把“Build Action”设为“Embedded Resource”也可以动态加载,不过原来的统一LoadXaml(string file)方法不再适用, 需要用到“反射”。

    把《动态加载XAML文件》一文中的工程,再添加一个btnEmbedded.xaml文件,内容和btn1等类似,设置属性的“Build Action”为“Embedded Resource”。在Page_Loaded中则用下述反射方法生成Button,文件名字需要“namespace+所在的位置”,typeof(Page)获取到该文件所在的程序集。

             //Build Action“Embeded Resource”XAML文件读取。//异常捕捉省略。

                String name = "LoadXaml.btns.btnEmbedded.xaml";

                System.IO.Stream stream = typeof(Page).Assembly.GetManifestResourceStream(name);

                String xaml = new System.IO.StreamReader(stream).ReadToEnd();

                Button btnEmb = (Button)System.Windows.Markup.XamlReader.Load(xaml);        

    把生成的XAP解压缩,反编译后可以看到,btnEmbedded.xaml文件位于Resources目录下,和LoadXaml.g.resources同级;而Build Action为Resource或Page的Xaml文件,则位于LoadXaml.g.resources之中。这就是为什么两者需要用不同的方法来加载。


    然而,上述两者同样最终都是在LoadXaml.dll程序集内,不像Build Action为“Content”的在Xap包内而在该程序集外,也不像Build Action为“None”的就根本不在Xap包内。只是提醒你复习下《Silverlight Resource 概览》。

     
    2009年03月27日 星期五 15:49
          在Silverlight中,Size、Rect、Rectangle、RectangleGeometry有点相像,有点关联,零星散落用到一个是一个,不如放在一块比较比较,联系联系,加深理解。

           Size其实是个结构体,只有一个构造函数,需要两个参数,描述对象的高度和宽度。示意如下:
            public struct Size
            {
                public Size(double width, double height)
                {
                    if ((width < 0.0) || (height < 0.0))
                    {
                        throw new ArgumentException();
                    }
                    this._width = width;
                    this._height = height;
                }
            }
           尽管宽和高是double,但尽量还应使用整数值。(PS:用double是为了和WPF兼容,此乃后话。)同时宽和高不能为负值,上限不是double.PositiveInfinity,而是一个由Silverlight本机的代码强制实施的较低数字,约为1,000,000.

           Rect和Size非常类似,也是结构体,但除了宽高之外,Rect还指定了原点(X,Y)。一般Rect用于与较低级别的图形表现相关的API,而Size用于与UI表现和布局相关的API。有三个构造函数,示意如下:
            public struct Rect
            {
                public Rect(double x, double y, double width, double height)
                {
                    if (width < 0.0)
                    {
                        throw new ArgumentException("", "width");
                    }
                    if (height < 0.0)
                    {
                        throw new ArgumentException("", "height");
                    }
                    this._x = x;
                    this._y = y;
                    this._width = width;
                    this._height = height;
                }
                public Rect(Point point1, Point point2);
                public Rect(Point location, Size size);
            }
           宽高情况与Size类似,(即不可以为负值,帮助文档中宽高可以为负值是错误的。)原点可以为负值,表示起点在布局之外。

           可见Rect本质就是一个值,这个值是个矩形区域。由于命名原因,常与Rectangle相混淆,其实这两兄弟基本就没联系。Rectangle是一个UI元素,隶属于Shape,仍在XAML中,出来的就是个矩形,还可以对这个矩形Shape填充颜色、增加事件等。代码示意:
    public sealed class Rectangle : Shape { }
          
           Rect、Rectangle哥俩还有一个胞弟叫RectangleGeometry,看名字就知道它与Rectangle的区别就在于Geometry和Shape的差异:Shape类有Fill、Stroke、Opacity等呈现属性,而Geometry类只能定义几何图形,无法呈现。Geometry最常用于两个用途:1,作为Path形状的Data属性,用来描绘内容。2,用于Clip其他UI元素。
    而RectangleGeometry有一个名字为Rect的属性,改属性的类型为Rect结构体。示意如下:
            public sealed class RectangleGeometry : Geometry
            {
                public Rect Rect { get; set; }
            }

           总结一下:
           Size和Rect,都是结构体,宽高定义类似,但后者多个原点定义。
           Rect和Rectangle,除了名字类似外,几乎不会用到一块。
           Rect和RectangleGeometry,Rect作为一个值,可以赋给RectangleGeometry的Rect属性。
           Rectangle和RectangleGeometry,两个都是密封类,由于继承自不同的父类Shape和Geometry,差异也一并显现。

      

           示例Rect和RectangleGeometry,有图片元素正常如左,被一RectangleGeometry剪辑,结果如右,示例代码:
           img.Clip = new RectangleGeometry { Rect = new Rect(40, 20, 100, 100)};
     
    2009年02月13日 星期五 16:22

             学习Silverlight的控件,不管是Core Controls,抑或是Toolkit Controls,甚至是第三方控件,除了掌握最基本的用法,常见属性、事件等,对控件的外观进行美化也非常必要。我原来习惯是直接对Templates 和 VSM进行手写修改,生产力低下。曾经简单试过Expression Blend,这两天又重新学习下,至少掌握怎么修改控件的Template,比如为某个状态变化加个动画什么的。

             一:认识“交互”面板。在Blend中创建动画,必须先熟悉下“交互”面板上常用按钮的基本作用。下图是来自Blend帮助文档WPF示例,和Silverlight基本一样,只注意“对象和时间线”里的几个重要按钮即可,更多的参考MSDN《“交互”面板》

    ⑷是Storyboard选项,初次点击是添加,之后可以删除、复制等。

           ⑾是播放指针,指示动画所在的时间点。可以在时间线中拖动播放指针,设置时间点,同时也可预览动画。

    关键帧,关键帧具有不同的级别:简单关键帧、复合关键帧、对象级关键帧等,以椭圆的大小区分。在关键帧上右键,可以删除,设置一些选项等。

           ⑺是记录关键帧 ,记录选定对象的属性在当前时间点的快照。也即点击一下添加一个关键帧,然后为这个关键帧选定相关属性的变化值。

             二:创建简单动画。在Expression Blend 中,动画由时间线组成,可在时间线上记录关键帧,以表示属性更改的时间设置。相关的几个按钮也已介绍,按照MSDN《创建简单动画》的步骤,清晰明了很快学会。动画的概念、分类不再本主题之列。

             三:修改控件模板。在Blend选中某个控件,右键选择“编辑控件部件(模板)”,然后单击“编辑副本”(修改默认模板)或“创建空项”(从空白创建)。出现 “创建样式资源”对话框,输入模板的名称。其中“定义位置”的三个选项代表着Style的应用域,应用程序所有文档中同样控件均可使用该模板、本文档中同样控件可使用、只有该文档中的该控件使用该模板。


    确定后即可开始修改模板。本小节更详尽的过程见MSDN创建系统控件的可重用模板》。

    四:修改模板的可选项。对于一个控件的原有模板,有哪些可以修改,或者自定义的呢?修改不同状态下控件的外观修改控件状态改变的过渡时间等。一般步骤就是选中某状态/状态变化,设置属性/时间的变化。具体可参考MSDN。


    还有就是为状态添加动画,使控件过渡到该状态后加以显示。有了上述基础,这也不是难事了,可参考添加状态改变后显示的动画

    写得有点虎头蛇尾,每个小节在MSDN上都有相关内容,只不过它分门别类的组织方式,不适合就某一个问题的线性解决,我把它们串了起来。学会修改系统控件的模板后,还可以把这个模板应用到其他控件上,同时自定义控件的模板创建也会方便得多。

    当然,Blend可学的内容也很多,比如单是设计可以成就《蛇蝎美女》,设计复杂的动画可以参考Lawrence的《使用XAMLBlend创建动画》,甚至构建3D动画都没问题。

     
    2009年01月07日 星期三 20:27

           枚举Key指定不特定于操作系统的可移植键代码。一般用于KeyDown和KeyUp事件的KeyEventArgs参数提供的Key值。(KeyEventArgs还包含以下属性,特定于操作系统的PlatformKeyCode,Handled和OriginalSource。)

           Key是一般的枚举,尽管号称“简易而不简单”,用起来注重简单即可,无需深究太多。KEYNONE为0;BACKSPACE为1到DELETE为19的特殊键;DIGIT0到DIGIT9,20到29;A到Z,30到55;F1到F12,56到67;剩下的是小键盘从NUMPAD0到DIVIDE,68到82;最后是个KEYUNKOWN,255。

           和Key枚举一样,在System.Windows.Input命名空间下,有一个KeyBoard类,这个类比较特殊,只有一个成员,是个属性,名称是Modifiers,返回值是枚举ModifierKeys。枚举ModifierKeys指定修改键集合,具有FlagsAttribute特性,即位标识,其成员值按位组合,每个都是2的某次方。俺就不再多解释位标记,简单说点技巧。ModifierKeys的定义大概如下:

    [FlagsAttribute]
    public enum ModifierKeys
    {
       None=0;       //没有按下任何修饰符
       Alt=1;       //按下Alt键
       Control=2;   //按下Ctrl键
       Shift=4;   //按下Shift键
       Windows=8;   //按下Windows徽标键
       Apple=8;   //按下Apple键(与Windows键不会同时存在?)
    }

           所谓位标记,就是按照二进制来看,每个bit代表了一个值,每个值其实也只有一位上是1。因此某个值与其他值按位与(&)的结果都是0,而不同值之间的按位或则可代表这几种值的组合。

    ModifierKeys.Shift & ModifierKeys.Control,即0010 & 0100 为 0;
    ModifierKeys.Shift | ModifierKeys.Control,即 0010 | 0100为0110,代表两个键都按下。

           而KeyBoard.Modifers代表目前所按下的修改键,若当前按下Shift键和Ctrl键,则KeyBoard.Modifers 的值为ModifierKeys.Shift | ModifierKeys.Shift。此时,

    KeyBoard.Modifers & ModifierKeys.Control == ModifierKeys.Control,即0110 & 0010 == 0010,

    用这个等式可判断Ctrl键是否被按下,同理有语句:

    bool shiftDown = KeyBoard.Modifers & ModifierKeys.Shift == ModifierKeys.Shift;
    bool shiftDown = KeyBoard.Modifers & ModifierKeys.Shift != 0;

    若shiftDown为true,则表面Shift键被按下。(但并不一定是只有Shift键被按下。)

           若要判断只有某修改键被按下,更为简单,只要判别则KeyBoard.Modifers的值即可:

    bool onlyCtrlDown = KeyBoard.Modifers == ModifierKeys.Control;    

           举一反三,判断某对修改键组合被按下,判断只有这对修改键组合被按下。(略)

           学习他人的代码,判断Ctrl键是否按下,这两者交替出现,搞得我不知道用哪个才好。要是有人讲解枚举时,拿Key和ModifierKeys做例子多么一举两得。

           Silverlight文档:修改键始终生成自己的键事件,可以选择处理这些事件,也可以选择跟踪自己的修改键状态,(PS:一般是在KeyDown事件和KeyUp事件里放置一个自定义的bool标记符跟踪。)但用Modifiers通常更为方便。

           附送一个在名称为tb的TextBox只能输入数字的代码片段,加深理解。

    private void tb_KeyDown(object sender, KeyEventArgs e)
    {
       bool shiftDown = KeyBoard.Modifers & ModifierKeys.Shift == ModifierKeys.Shift;
       if((e.Key < Key.D0) || (e.Key > Key.Z) && (e.Key < Key.Multiply))
       {
           return;
       }
       if(e.Key > Key.D9)
       {
           e.Handler = true;
       }
       else if(shiftDown)
       {
           e.Handler = true;
       }
    }

     
    2008年12月05日 星期五 13:43

    本文对应于Silverlight 2帮助文档中“Application Model”章节,微软的介绍顺序或许着眼于宏观架构,而本文则属于问题导向型的介绍。在实际中遇到初始化化页面加载其他xap中的应用程序调用资源文件等问题,在解决过程,不断的参考阅读了这部分内容。尽管单一逐个地解决了问题,但重新组织,并整理下自己的思路,理解将会更加深刻。

            

    Application类封装了一个Silverlight应用程序(单例模式),它主要表示应用程序代码在 Silverlight 插件生命周期中的入口点(插件激活过程可参考下图)。提供若干服务:应用程序生存期管理、 应用程序资源文件加载、 未处理的异常处理和Web 宿主集成等。(“Application Service”)

    Application类有三个事件成员:Startup、Exit和UnhandledException。在新创建Silverlight应用程序时,在自动生成的App.xaml.cs会看到相应事件的处理方法。Exit和UnhandledExeption可查看帮助文档,暂时只关注Startup事件。

      

    Startup用来在应用程序启动时进行一些初始化操作,最基本的指定RootVisual属性来显示主页面。其次就是检索传进来的参数StartupEventArgs 对象的 InitParams 属性,进行相应的处理,比如如何确定不同的起始主页面,参考TerryLee的《Silverlight 2应用程序中切换用户控件》。还可以通过HtmlDocument.QueryString从宿主网页中检索URL参数,通过IsolatedStorageSettings类检索先前应用程序的会话数据等。

      

    此外,Startup中也可以检索其他资源,比如用WebClinet等异步下载其他资源文件或程序集。若文件为Zip或xap,则要利用到Application.GetResourceStream方法。若文件为程序集,则要创建一个新的AssemblyPart对象,并调用它的Load方法来进行加载。当然,调用其他资源文件,也可不必Startup中进行。比如可以在某页面中点击按钮来触发事件,调用其他xap中的某个程序集。

       

    理解调用外部xap中程序集的过程,首先需要了解“Application Structure”,查看并理解AppManifest.xaml文件。需要注意的是,beta2中用Deployment对象来获取AppManifest.xaml文件中的元素已不再有效,可以利用Linq方式读取。可参考《Dynamic Load & Invoke Other Xap For SilverLight 2.0》,内容是中文的,这篇文章有改进之处,比如把这个过程抽象为一个方法,可供以后直接调用。

            

    Application类处理上面提到的Application.GetResourceStream方法外,还有一个常见的方法就是Application.LoadComponent。查看page等页面构造函数中InitializeComponent()方法即可看到它的出现。该方法也常用来调用“Build Action”为“Page”的xaml文件,参考《动态加载XAML文件》。

           

    Application还有其他方法,不再逐一介绍。最后看一下Application的属性,Current、Host、Resource和RootVisual。

           

    Application.Current用来提供对当前应用程序的 Application 实例的共享访问。由于一般系统自动生成的是从Appliction继承的App类,因此常见形式为:App currentApp = (App)Application.Current;

    Host,获取有关 Silverlight 应用程序的主机的各种详细信息。比如txtBlock.Text = App.Current.Host.Background;

    Application.Resource常出现在App.xaml文件中,指应用于整个应用程序的资源。相对的就是单一页面域的资源和inline式资源。

    RootVisual就来获取或指定应用程序的起始页面。

          

    更复杂的是覆盖自动生成的继承自Applicaitonde的App类,自定义实现一个继承自Application的类,略


     

    2008年10月22日 星期三 22:28

    Silverlight 2 安装倒也不是什么难事,不过在我升级的时候确实遇到些问题,同时也有人一直在问,Silverlight.net的Get Started页面给出的说明也过于简单,就把升级安装过程复述一遍。

    1把先前安装的所有关于Silverlight的软件、运行时等统统卸载。包括Expression Blend 2.5 Preview和老版的Deep Zoom Composer。以前没有安装过无需多虑。

    2 确定VS2008打了SP1的补丁,英文版的打英文版的补丁,中文有中文的补丁。

    3 类似上条,英文VS2008安装英文的Silverlight_Tools,中文的安装中文的。相应软件在微软的网站上都可以下载到。

    4 如果你的机子连接着网络,没什么意外都会安装成功。既然安装Silverlight_Tools,即开发工具,运行时即Silverlight.2.0就无需安装。

    基本的工作已经完成,但或许还想使用其他的工具,继续。

    5 安装Expression Blend 2试用版,然后才可以安装Get Started页面提到的Expression Blend 2 SP1。SP1的下载页面有Blend 2的链接,SP1暂时只有英文版,因此在下载Blend 2的时候最好也选择英文。

    6 直接安装新版本的Deep Zoom Composer。

    是以至此,基本就没什么事了。然而就怕有些有时候,不得已在不能连网的机子上安装开发工具,这时候就郁闷了。因为第4步在安装Silverlight_Tools的时候,微软偷偷摸摸的又下载了个约6.7M的Silverlight.2.0_Developer安装文件。

    不联网,就只有等着安装失败了。不过办法总是有的:

    4.1 去这里http://go.microsoft.com/fwlink/?LinkId=127693 下载下一步安装时必需的文件Silverlight.2.0_Develope.exe。

    4.2 启动相应语言版本的Silverlight_Tools.exe,这时会看到它自动解压缩出一个文件夹,不用点击下一步。找到刚才解压出来的文件夹,把刚才下载的Silverlight.2.0_Develope.exe放到该文件夹下。同时不要关闭安装对话框,否则解压缩出来的文件夹会消失。

    4.3 启动该文件夹下的SPInstaller.exe,进行安装,即可成功。

    4.4 最后退出启动Silverlight_Tools.exe时出现的对话框。

    其实,学习或者说使用软件,如果在安装过程中就卡壳,常常会觉得非常丧气和郁闷,对这个软件或工具就没有什么好感,一如数年前安装盗版ArcGIS。我就不爽了大半天,最后好歹在Silverlight.net论坛里找到了相似问题的答案。

    此外还有一个问题就是,下载Scott的教程DiggSample,什么都不改动,就发现Page.xaml不能预览,会报错“元素 StoryDetailsView 的未知属性 Name”,就是在Page.xaml页面调用另一个名为StoryDetailsView的UserControl时报错。这也太打击人了,什么都没有改动,版本也一致,愣是报错,十分的烦躁。

    其实这个问题在beta2中就发现了,只不过是运行时程序没什么错误,将就着预览就只能用Blend,当时也认为或许自己有什么错误不晓得。现在肯定是微软的又一个bug,真是有点不知道说什么,浪费时间和否定自己。Silverlight.net论坛里的帖子“RC0 Unknown attribute Name on element ...”,表明非常之多的人也遇到了同样的问题。差不多一个月了,没人出来解决,也没人解释,哎……

     
    2008年10月15日 星期三 17:03

    Silverlight 2 提供了System.Windows.Markup.XamlReader.Load(string xaml)来动态的创建XAML,但这差不多限于短小的xaml片段创建,若要是从xaml文件直接读取创建,则写一个函数LoadXaml比较现实。

    XAML文件本身也是资源,因此资源的Build Action(生成操作)不同,则引用该文件的uri也不同。例如build action"Resource"时,资源文件嵌入到程序集中;为"Content"时,只打包进.xap中等等,可参考《Silverlight Resource 概览》。

    代码比描述更能表达意思,参考解决方案资源管理器和运行结果图示。btn1.xaml文件里其实也仅仅拿了个button作为示例:<Button xmlns='http://schemas.microsoft.com/client/2007' Width="60" Height="50" Margin="10" Content="Page"></Button>btn2.xamlbtn3.xaml只是用Content的不同来显示不同的Build ActionbtnRed是用string方式创建的,btnDef则是因为错误的引用xaml文件。page.xaml里有一个名称为spStackPanle来承载这些button,别的没有。今天比较烦躁,OverSilverlight 2昨晚6点正式发布,这周末再考虑升级。

       public partial class Page : UserControl
        {
            public Page()
            {
                InitializeComponent();
                this.Loaded += new RoutedEventHandler(Page_Loaded);
            }

            private void Page_Loaded(object sender, RoutedEventArgs e)
            {
                //Silverligh2 提供 XamlReader.Load(string xaml) 片段式 创建xaml。
                //命名空间"http://schemas.microsoft.com/client/2007" 不能少。
                string buttonXAML = "<Button xmlns='http://schemas.microsoft.com/client/2007' Width=""60"" Height=""50"" Content=""string"" Margin=""10"" Foreground=""Red""></Button>";
                Button btnRed = (Button)System.Windows.Markup.XamlReader.Load(buttonXAML);
                sp.Children.Add(btnRed);

                //从文件创建,该文件 的Build Action 为 "Page", 与"Resource"类似,被嵌入程序集内
                Button btn1 = (Button)LoadXaml("/LoadXaml;component/btns/btn1.xaml");
                sp.Children.Add(btn1);

                //从文件创建,该文件 的Build Action 为 "Resource",被嵌入程序集内
                //注意格式:"/命名空间;component/文件位置"
                Button btn2 = (Button)LoadXaml("/LoadXaml;component/btns/btn2.xaml");
                sp.Children.Add(btn2);

                //从文件创建,该文件 的Build Action 为 "Content",仅打包进.xap中,不在任何程序集内
                Button btn3 = (Button)LoadXaml("btns/btn3.xaml");
                sp.Children.Add(btn3);

                //从错误的文件创建,最终生成的是默认的对象
                Button btnDef = (Button)LoadXaml("btns/btn4.xaml");
                sp.Children.Add(btnDef);
            }

            /// <summary>
            /// 从xaml文件中 创建 xaml对象
            /// </summary>
            /// <param name="file">xaml文件的"地址"</param>
            /// <returns>返回xaml文件定义的对象</returns>
            public static object LoadXaml(string file)
            {
                Uri fileUri = new Uri(file, UriKind.Relative);
                System.Windows.Resources.StreamResourceInfo streamInfo = System.Windows.Application.GetResourceStream(fileUri);

                if ((streamInfo != null) && (streamInfo.Stream != null))
                {
                    using (System.IO.StreamReader reader = new System.IO.StreamReader(streamInfo.Stream))
                    {
                        return System.Windows.Markup.XamlReader.Load(reader.ReadToEnd());
                    }
                }

                //若文件不存在,则返回默认创建的对象
                return CreateDefaultObject();
            }

            //创建默认对象,以一个简单的button为例
            public static object CreateDefaultObject()
            {
                Button btn = new Button();
                btn.Width = 60;
                btn.Height = 50;
                btn.Margin = new Thickness(10);
                btn.Foreground = new SolidColorBrush(Colors.Blue);
                btn.Content = "Default";
                return btn;
            }

        }

    update:相关文章 20090423 《用反射来动态加载XAML》。

     
    2008年10月12日 星期日 11:01

    图片,音频、视频,甚至XML和XAML等非执行数据文件都叫做资源,根据资源所处位置的不同而有所区别,先了解下Silverlight 应用程序的结构。

    在.xap压缩包中,有一个Appmanifest.xaml文件,定义了打包的程序集和应用程序入口;一个application程序集;0个或多个library程序集;0个或多个资源文件,如图片、视频等。整个.xap在应用程序激活之前都已经下载到客户本地,而on-demand文件,顾名思义,需要的时候再予以加载。

    由此可见,资源文件可分布在多个位置,如镶嵌入程序集内;在.xap压缩包内而不镶嵌入任何程序集内;不在程序集内也不在.xap内。当在工程中添加一个资源如pink.png图片时,右键之,选择属性,可以在“Build Action”中,分别选择ResourceContent None 可使资源文件生成在对应上述三个位置。(其他选项在Silverlight中没什么作用)

    在工程中引入资源文件,即引入在与page.xaml同目录下,默认的“Build Action”选项是“Resource”,即镶嵌入相应程序集内,这时引用该资源不应该以反斜杠开头。若把资源文件放在ClienBin同目录下,则相当于None,引用时需要以反斜杠开头。可参见《Silverlight Image Source URI》一文,理解是否以反斜杠开头的区别。

            不建议把资源文件放在page.xaml同目录下,然后选择“Build Action”为“None”,换句话说,若不想资源文件打包进.xap中,直接把资源文件放在ClienBin文件目录下。但可以把page.xaml同目下的资源文件属性中的Build Action”改为“Content”,使其放在.xap压缩包中,方便.xap中多个程序集的共同使用。既然此时资源文件在.xap压缩包内,引用该文件则需要以反斜杠开头。这就是《Silverlight Image Source URI》一文最后提到的,为什么资源文件放在page.xaml同目录下,却可以使用反斜杠开头来引用。示例代码和运行结果如下。

    <StackPanel Background="White" Orientation="Vertical">
            <Image x:Name="blue" Source="/images/blue.png" Stretch="None"/>
            <Image x:Name="green" Source="images/green.png" Stretch="None" />
            <Image x:Name="pink" Source="/images/pink.png" Stretch="None" />
    </StackPanel>

    对应Silverlight应用程序结构,本示例三个资源文件,ClientBin目录下(包含下级目录,只不过把所有Image都放在一个文件夹里了)的blue.png是按需索取的松散资源,没有镶嵌到任何程序集内;page.xaml同目录下的green.pngBuild ActionResource,最终其被生成在.xap压缩包内的dll文件中,即镶嵌到了application程序集中;而pink.png由于Build Action被更改为Content,生成后,其位于.xap压缩包内,(故而需要反斜杠开头来引用)但不在任何程序集。

     
    2008年10月10日 星期五 10:48

    Isolated Storage技术就是让你的Silverlight程序可以在用户的硬盘上创建文件,存储数据。下次访问时,应用程序可以读取这些数据,进行相关操作。当然,用户通过Silverlight设置可以禁用这个功能。

    在很大程度上,Isolated Storage可以称为下一代Cookies,你可以存储更多的东东,可以有着更精准的控制。常见的用法就是在用户的硬盘上创建目录和文件,存储二进制数据等。默认的允许存储空间是1000KB,可以通过 IncreaseQuotaTo 方法向用户请求分配新配额空间。    

    可以通过IsolatedStorageSettings类(dictionary, name/value)的成员来进行存储设置,支持应用程序配置(ApplicationSettings)和站点配置(SiteSettings)两种。后者允许一个域名domain下访问同一个配置的数据。但由于是存储在电脑的磁盘上,自然不支持漫游(roaming)访问,即一个用户换了一台电脑,则应用程序就不能访问原先的设置了。

    大致的操作有:获取应用程序的Isolated Storage,创建一个包含目录和文件的文件系统,读写数据,删除文件,查找目录,请求新的配额空间,删除存储等。

    此外,这些文件在VISTA下存储在:C:"Users"用户名"AppData"LocalLow"目录系统下。具体的示例代码、介绍在chm的帮助文档Isolated Storage下都有,我不啰嗦了。Jesse Liberty的《Isolated Storage – Might Be Easier Than You Think 也非常实用。偷个他示例(V2rc0)的图。


            后记:接触
    Silverlight以来,经常看见Isolated Storage 出现,让我疑惑这究竟是什么玩意,是不是很重要,在我写的demo中加入它是否可以提高效率什么的?终于抽出时间来看看,由于原来没接触过这个概念,先从中文介绍入手,结果看了数篇仍然云里雾里,不知道作者在自言自语说些什么,有些博客作者也很诚实,自己刚接触也不甚理解,靠,那样你还敢写什么介绍啊教程啊,让我看得更郁闷。

    受不了你们了,直接看英文介绍吧。号称Silverlight Geek Jesse Liberty的上述文章让我大为释疑,再翻翻帮助文档,知道了它是什么,干什么用,什么时候需要用,这是最重要的。至于怎么用,那是纯技术的后话。最近搞这个,一直浸淫在英文书籍、文档、博客里,但偶尔发现新的名词,还总是不自觉的想看下中文的介绍,以为会更容易懂,看来未必如此!

     
    2008年09月26日 星期五 11:05

    924日到926日,微软DPE部门邀请了国内一些合作伙伴去参加WPF+Silverlight Deep Dive Training,讲师是Jaime Rodriguez Laurence Moroney。第一天两位讲师分别概要介绍了WPFSilverlight的相关知识,来听课的有些已经用这些技术在做实际工作了,有些还没有怎么接触过。第二天第三天主要是各个公司轮流和讲师单独的交流。今天,也即第三天如果时间充裕的话,好像还有个小比赛?没去我就不得而知了。

    这是俺走出校门两个月后的第一次参加这样子的活动,收获还是比较大的。从技术方面来讲,最大的感受是我知道了Silverlight不能做什么,先前铺天盖地的介绍评论,不管是褒扬还是批评,都集中在Silverlight能做什么,能做成什么样子,而几乎很少有人提及Silverlight位于什么位置,究竟为什么而生,Flash杀手?不仅仅如此。云计算,今年非常火的概念,微软也会做出响应,且看今年1028日举行的“微软专业开发者大会”(PDC)。从与他人交流方面讲,学校与社会大相径庭,当我问别人公司与Email时,别人却来和我交换名片,可惜我没有@_@等等。

    值得一提的是,和Laurence Moroney相对比较熟悉了。第一天晚上微软组织了一场晚餐聚会,期间玩的游戏是杀人,我坐在两位讲师的旁边,并且和Laurence Moroney同为杀手团队成员,期间互相指责混淆视线等等,有不错的交流。第二天单独交流时,把我做Demo过程中百思不得其解的问题展示给了他,他琢磨了琢磨,说:You're lucky, and you have found a bug! 呵呵,膨胀了下自我满足心理,发现了微软的bug!(Canvas在没有设置Background属性时,不能响应鼠标事件)又问了其他两个问题,汗下自己的口语,表达不够顺畅,多谢某微软员工的帮忙,有机会多练习练习才是。临走,他送了本签名的《Introducing Silverlight 2》,定价约$35,亚马孙7折,呼呼。以后有什么问题,相信和他直接Email交流顺理成章了。

    微软这样的大公司其实也非常谦和的,在回答和Flash的比较时,他们大致说没有做出太多的比较,(Silverlight定位不仅仅是针对Flash)但也回答了许多,期间多用Catch up with这个词语,Flash十多年的历史,而Silverlight不过十多月的时间,没有刻意贬低对手,夸大自我!比较搞笑的是,第一天讲师提了个问题,微软中国DPE的刘经理失口说,大家可以用Google搜索下,这时Jaime Rodriguez 就不干了wow, wow了两声,哄堂大笑。其实,他自己在展示Demo时,IE浏览器右上角的搜索引擎也是Google

    微软的培训组织的不错,活动、小礼品(基本上提问的都得到了优盘或签名的书)、吃饭等,就是某个“同学”比较恶心,课堂电话一个接一个声音还老大,哎!其他的同学各有各的特点,特别张扬的有,低调却非常有实力的也有……

    PS:培训的时候用的Silverlight 2 RC版,而今天微软官方也正式放出了RC版,具体介绍参见《Silverlight 2 Release Candidate Now Available 》,正式版很快就见面!


    2008年09月18日 星期四 21:22

    出于安全问题考虑,在Silverlight应用程序中从其他地方获取图片、音频、视频,以及XAML文件、字体文件等资源时,所使用的URL会有些限制。这些URLs分为三类:

    Cross-scheme URL:譬如HTTP下的Silverlight应用程序试图获取HTTPS下的资源是不被允许的。

    Cross-domain URL:这个在Ajax等地方比较常见,就是从一个服务器获取另一个服务器上的资源,这时需要看安全策略文件是否允许。

    Cross-zone URL:在IE的工具菜单下的安全选项卡上,我们可以看到分四个区域:Internet, Local intranet, Trusted sites(可信站点)和Restricted sites(受限站点)。此外,the local machine(本地机器)也被看做是一个区域。Cross-zone主要防止Internet上的程序来访问Local intranet的资源,当然本地的程序访问互联网的资源肯定不受限制,只要别人允许即可。因为zone是在IE上的划分,因此这个概念在苹果机上暂不支持。

    下表摘要性的描述了在Silverlight中通过WebClient或 HTTP类以及其他组件访问URL的限制规则,原图和原文(这篇博客差不多就是简要翻译):URL Access Restrictions in Silverlight 2


    后记:我在编写小程序时,请求自己机子上的图片,使用http://localhost/test.png。后来发给局域网的同学测试,发现不能正常出图。Google了下,发现他人类似的错误是由于Cross-scheme。到我这里的错误具体应该是Cross-zone,当同学运行我的程序,访问地址是http://liongg/silverlight/default.aspx,此时在程序内部,向localhost,即同学的机子请求图片,一来他机子上可能没相应图片,最重要的这是不允许的:互联网、局域网的应用程序试图获取你自己电脑上的资源!

    当我翻阅Silverlight Document时,发现相关篇章我先前阅读,并做过简要笔记,但竟然仍旧犯错误,而且是搜索到这里才查阅的。想来或许些许郁闷,但也无需太过自责,很多功能、用法只有实践过、错过,才会对其印象深刻并掌握,即便先前看过,很多东西也不是看一遍就清楚理解其内容。

    反正跨域这玩意,现在也不是什么太大的问题,一般都有打包解决方案,譬如在做豆友地图时就发现,可以使用 JSONP 方式来支持跨域调用豆瓣API等等。

     
    2008年09月13日 星期六 22:07
    Silverlight2 现在支持的Image格式有jpg和png,部分png编码也不支持,同时有些png在xaml的design预览中不可见,但运行时可见。请看XAML markup中两行代码的异同:
    <StackPanel Background="White" Orientation="Vertical">
            <Image x:Name="blue" Source="/images/blue.png" Stretch="None"/>
            <Image x:Name="green" Source="images/green.png" Stretch="None" />
    </StackPanel>

    反斜杠forward-slash?有没有虾米区别呢?如图所示,名称为Resource测试示例解决方案资源管理器以及运行效果:以反斜杠开头的blue图片需要放在ClientBin目录下的相应文件夹里;不以反斜杠开头的green图片应该放在Resource目录下的相应文件夹里。这样才可正确引用,否则会发生ImageError。


    为什么?两者都是相对路径,到底反斜杠带来了什么区别呢?反斜杠开头的相对路径,代表的相对位置是应用程序运行的根目录,即.xap压缩包内,若在这其中寻找不到要引用的文件,则相对路径的回退机制(fallback mechanism )自动在在.xap所在的目录,本例即为ClientBin目录中寻找加以引用。两个位置都没有,才会发生错误。不以"/"开头,则代表的相对位置是引用该图片的XAML文件所在的目录,本例即page.xaml文件所在的Resource目录。

    那么究竟选择哪种方式呢?把xap文件重命名为zip文件,解压之,再用reflector反编译其中的dll文件,发现其包含了green图片,却没有blue图片。其实也很明显,blue所在的images文件夹与.xap同级,自然不会包含在内。由此可知,不以反斜杠开头的green图片嵌入到Silverlight程序中的xap文件直接下载到客户端,而blue图片则按需索取(on-demand),当显示时再去下载。当数据量较大时,不以反斜杠开头的方式加载程序的时间就过长,用户体验不好,以"/"开头自然就无此无虑,不过以反斜杠开头的话,在xaml中设计预览看不到,只有程序运行才可以看到。(若为了预览,可先从ClienBin那里复制一份放在page.xaml同级目录下供设计使用,程序发布时予以删除。)
            
    除了在XAML中直接确定Image的Source URI,当然也可以在code-behind中确定,此时反斜杠的用法和XAML中相通。
    C#:Image img = new Image();
    img.Source = new BitmapImage(new Uri("test.jpg", UriKind.Relative));      //page.xaml所在目录下
    //img.Source = new BitmapImage(new Uri("/test.jpg", UriKind.Relative)); //.xap所在目录下

    话说要是使用诸如http://www.liongg.net/test.jpg之类绝对URI就没反斜杠什么事了。在代码中还可以利用Application.Current.Host.Source.AbsolutePath等方法,我试验下了,发觉太麻烦还没意思,不再多管。

    再深入一点,甚至图片放在与page.xaml同级的文件夹下,一样可以使用反斜杠进行引用。只需要在相应图片的属性里,把Build Action选择为"Content"即可,不过该图片还是被放到.xap压缩包里了,这是后话,参见《Sivlerlight Resource 概览》。
  • 相关阅读:
    bzoj千题计划239:bzoj4069: [Apio2015]巴厘岛的雕塑
    bzoj千题计划238:bzoj3668: [Noi2014]起床困难综合症
    hdu 3022 Sum of Digits
    在RAC中,当私有网线拔了后,会怎么样?
    CVU介绍
    oracle rac 日志体系结构!
    oracle 内存结构 share pool sql解析的过程
    Oracle逻辑读详解
    共享池之八:软解析、硬解析、软软解析 详解一条SQL在library cache中解析涉及的锁
    共享池之六:shared pool latch/ library cache latch /lock pin 简介
  • 原文地址:https://www.cnblogs.com/bingyun84/p/1504480.html
Copyright © 2011-2022 走看看