silverlight获取网页里的资源文件

silverlight获取网页里的资源文件,第1张

概述内容来源http://longer3436.blog.163.com/blog/static/12833062200987104249150/该博客 Silverlight 3 Theme研究 Silverlight 2009-09-07 22:42:49 阅读503 评论0   字号:大中小 订阅     Silverlight 3对于主题也有了很好的支持,在toolkit中已经提供了不少主题,

内容来源http://longer3436.blog.163.com/blog/static/12833062200987104249150/该博客

Silverlight 3 theme研究

Silverlight 2009-09-07 22:42:49 阅读503 评论0   字号: 订阅

 

 

Silverlight 3对于主题也有了很好的支持,在toolkit中已经提供了不少主题,当然也可能自己设计主题了,只要有一个xaml文件就够了,这样设计人员之间就能够共享主题。这里主要总结两个东西,一个是关于隐式主题,另一个当然就是显式的啦。

ImplicitStyle

什么是隐式样式?知道CSS的大概就知道是什么意思了。在SL中写一个Style的话,除了需要指明其targettype,还需要指定一个Key,这样在控件中使用Style={StaticResource Keyname}的方式来加载Style。而隐式样式则不需要指定Key,也就是说如果指定了一个隐式样式的targettype并且在项目或者某个Layout的控件中引用了这个样式,那么在项目或控件内部所有那种类型的控件都会应用那个样式,这样就不用一个一个控件地写Style=了,自然是方便不少。

正是因为所有同类型的控件都会加载同样的Style,可能在设计的时候并不希望这样,总是有一些是特别的。没有关系,因为隐式样式的优先级比较低,如果你设置了其他的样式的话自然会覆盖掉隐式样式的。

好了,现在来总结一下如何使用ImplictStyle。

使用隐式样式,首先要添加toolkit的System.windows.Controls.Theming.Toolkit.dll程序集,当然在需要使用的xaml中也要添加相应的命名空间啦。现在添加一个新的User Control,就叫TestStyle吧。首先添加命名空间:

 

 

xmlns:theme="clr-namespace:System.windows.Controls.Theming;assembly=System.windows.Controls.Theming.Toolkit"

 

然后添加一个StackPanel吧,在里面添加一个按钮,然后设定样式:

 

 

<button Content="button" WIDth="100" Height="22" x:name="button" ></button>

 

当然了,这个按钮的样式现在还没有写,接下来的工作就是要添加这样一个样式了。文件放置的位置无所谓了,这里按照微软的习惯,先建立一个文件夹,名字为Assets,然后在里面添加一个xaml文件,叫Styles.xaml,样式就写在这个文件里

 

 

<ResourceDictionary

  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

  xmlns:navigation="clr-namespace:System.windows.Controls;assembly=System.windows.Controls.Navigation"

    xmlns:uc="clr-namespace:TestControl;assembly=TestControl"

    xmlns:common="clr-namespace:Common;assembly=Common"

    >

   

    <Style targettype="button">

        <Setter Property="Foreground" Value="Red"></Setter>

    </Style>

/ResourceDictionary>

 

这个时候如果直接运行会发现,按钮的样式并没有改变。这个时候toolkit的ImplicitStyleManager就该出场了,可以在任意的Layout控件中使用,现在我们就在StackPanel中添加吧:

 

 

 <StackPanel x:name="LayoutRoot" theme:ImplicitStyleManager.ApplyMode="auto" theme:ImplicitStyleManager.ResourceDictionaryUri="Assets/Styles.xaml" Background="White" >

 

上面的代码指定了两个东西,一个是隐式样式的添加模式,有三种:none、auto和onetime。none就跟你没有写ApplyMode的效果是一样的,而onetime就是只加载一次了,auto则允许多次加载。另一个就是ResourceDictionaryUri,它指定了隐式样式所在的文件。

那么好吧,现在直接运行一下?很不幸,程序可以编译通过,但是运行的时候出错了。这是因为ImplicitStyleManager无法找到相应的资源。那怎么办呢,很简单,Styles.xaml文件在新建的时候,其默认的“Build action”是page,这样隐式样式是无法加载的,我们需要把它改为Content。在Styles.xaml上右键,选择属性,将Build Action 改为Content。运行下程序,OK了,按钮的字体变成红色了:

并且我们可以看到,在StackPanel外面的button是不受这个隐式样式的影响的,比如:

 

 

<StackPanel x:name="LayoutRoot" Background="White" ><!---->    

          <button Content="button without style" WIDth="200" Height="22"></button>

        <StackPanel theme:ImplicitStyleManager.ApplyMode="auto" theme:ImplicitStyleManager.ResourceDictionaryUri="Assets/Styles.xaml" >

        <button Content="button" WIDth="200" Height="22" x:name="button"></button>

         </StackPanel>

</StackPanel>

 

这样运行的结果将是:

这个结果正是我们希望的。同样,即使是在Layout控件内部的,如果已经定义了样式或对相应属性进行了设置,也是会覆盖隐式样式的。至于说隐式样式到底是怎么起作用的,这个就要涉及AttachProperty,比较麻烦了,这里暂时不讲,可以到网上搜一下。

还有一点要说的是,ResourceDictionaryUri是全局的,不仅可以在这里指定,在其他地方也可以指定,最后使用哪个路径就看哪个最后加载了。

在预编译的时候设定样式是很顺利了,那么在运行时又该如何改变呢?其实也非常简单,现在就来做个小测试吧。

首先添加一个按钮,其作用就是改变样式。然后依照刚才的方法,在Assets文件夹中添加一个新的xaml文件,将按钮的字体颜色设置为绿色。注意别忘了把Build Action改为了Content。这时需要对xaml文件作一些修改:

 

 

<button Content="button without style" WIDth="200" Height="22"></button>

        <StackPanel x:name="Container" theme:ImplicitStyleManager.ApplyMode="auto" theme:ImplicitStyleManager.ResourceDictionaryUri="Assets/Styles.xaml" >

        <button Content="button" WIDth="200" Height="22" x:name="button"></button>

        <button Content="change style" WIDth="100" Height="22" Foreground="Black" Click="button_Click" ></button>

    </StackPanel>

 

然后在后台添加代码:

 

 

  private bool _change = false;

        private voID button_Click(object sender,RoutedEventArgs e)

        {

            if (_change)

            {

                ImplicitStyleManager.SetResourceDictionaryUri(this.Container,new Uri("Assets/GreenStyles.xaml",UriKind.relativeOrabsolute));

            }

            else

            {

                ImplicitStyleManager.SetResourceDictionaryUri(this.Container,new Uri("Assets/Styles.xaml",UriKind.relativeOrabsolute));

            }

            ImplicitStyleManager.SetApplyMode(this.Container,ImplicitStylesApplyMode.auto);

            ImplicitStyleManager.Apply(this.Container);

            _change = !_change;

}

 

运行一下就可以看到了,添加了隐式样式的按钮,在点击之后按钮的样式就会改变,而没添加的按钮就不收影响。需要对上面的代码作一个简单的说明,调用SetResourceDictionaryUri方法来改变当前的样式文件的路径,这样可以调用不同的样式了,但是仅仅是这样是不会立刻改变的,还需要调用SetApplyMode方法设置模式,并调用Apply方法来提交改变,这样就能达到目的了。不过需要注意的是这几个方法传递的参数,第一个参数都是你想要Attach相应的样式的控件,比如我现在就是将样式Attach到StackPanel中,这样只有在里面的button才会受影响。而如果我把“this.Container”改成“this”,那么整个UserControl都会Attach这个样式,其结果就是即使是在StackPanel外面的那个button样式也会改变。

就跟显式样式会优于隐式样式一样,隐式样式自己也是有优先级的关系的。就像上面说的,如果在UserControl上Attach样式,但是如果在StackPanel上同样也Attach了,并且指定了ResourceDictionaryUri,那么在StackPanel里面的button的样式就不会改变了。简单来说,就是父控件样式的范围会更广,而子控件样式的优先级会比较高。

最后还有一点想要说明的是,之前的测试都是在同一个工程里面的,如果在解决方案下有多个工程,那么在其他工程中该如何使用呢?其实是一样的,并不需要做什么改动。

好了,关于隐式样式的内容就是那么多了,再来总结一下显示样式吧。

theme

我想写过Silverlight程序的人大多应该有这样的体会:写Style真是件让人很痛苦的事。因为随便一个什么样式都很可能会写上上百行甚至数百行或者更多。而以前全局的样式只能写在App.xaml里面,这样直接导致的一个结果就是这个文件会变得超大,大得让人无法忍受,除了打开会很慢很慢外,想要从中找出个什么东西来也是非常困难的一件事。现在就不一样了,允许将样式文件分放到不同的地方,这真是个很好的改进。现在来看看这个东西是怎么工作的吧。

为了简便起见还是用刚才定义的两个样式文件:Styles.xaml和GreenStyles.xaml。如果是显式样式的话,其Build Action似乎不是很重要(具体还没详细研究),无论是page还是Content都可以正常工作,因此就不改了。唯一做的改动就是给每个样式添加一个key,就叫buttonStyle好了。

 

 

 <Style x:Key="buttonStyle" targettype="button">

        <Setter Property="Foreground" Value="Red"></Setter>

    </Style>

 

接下来就是要改动app.xaml了:

 

 

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             x:Class="TestControl.App"

             >

    <Application.Resources>

        <ResourceDictionary>

            <ResourceDictionary.MergedDictionarIEs >

                <ResourceDictionary  Source="Assets/Styles.xaml"></ResourceDictionary>

            </ResourceDictionary.MergedDictionarIEs>

        </ResourceDictionary>

    </Application.Resources>

</Application>

 

可以看到,我在Application.Resources里面添加了一个ResourceDictionary,同时又在其MergedDictionarIEs 里面再添加了一个ResourceDictionary ,在最后这个ResourceDictionary 里面指定其Source是事先写好的Style文件的路径,这样就可以全局调用这个资源了。调用的方法跟普通的样式是一样的,如下:

 

 

<button Content="button" WIDth="200" Height="22" x:name="button" Style="{StaticResource buttonStyle}" ></button>

 

这样button就添加了样式了。

MergedDictionarIEs 是一个集合,有了这个东西,ResourceDictionary里面可以再添加ResourceDictionary,这样就能把样式分开到不同的文件了,是不是方便很多呢?最关键的还不是这里,有了这个东西就可以很方便的改变样式了哦,因此改变主题也就不是那么困难了。那么下面再来通过一个小例子说明下如果动态改变主题吧。

还是像刚才那样,点击一下按钮样式就改变,但是代码要做相应的变动:

 

 

 App.Current.Resources.MergedDictionarIEs.Clear();

            if (_change)

            {

                App.Current.Resources.MergedDictionarIEs.Add(new ResourceDictionary() { Source = new Uri("/Assets/Styles.xaml",UriKind.relativeOrabsolute) });

            }

            else

            {

                App.Current.Resources.MergedDictionarIEs.Add(new ResourceDictionary() { Source = new Uri("/Assets/GreenStyles.xaml",UriKind.relativeOrabsolute) });

            }

            his.button.Style = App.Current.Resources["buttonStyle"] as Style;

 

上面的代码跟之前的隐式样式有些不同,首先是要将MergedDictionarIEs清除掉,然后添加新的资源,但是这样并不会马上改变控件的样式,还需要显示地设置其style才行,或者重新加载页面。这里有一个地方尤其需要注意的,请仔细观察两个方法设置xaml文件路径的异同,细心点可以发现,在显式样式的时候前面多了一个斜杠!这个是必须的,否则编译不通过,会抛出“对 COM 组件的调用返回了错误 HRESulT E_FAIL。”这么一个异常,原因是无法找到相应的资源(我以后哈,不是特别确定)。关于这点,就要涉及到Silverlight关于资源的引用的问题了,这里不想多说,引用同事Kevin Yang博客的一片文章中的一段话来简要说明一下吧:

 

Resource —— 资源会被打包在程序集内部 Content——资源会被打包在Xap包里面 None——资源既不会被集成到程序集内,也不会打包到xap包中。不过我们可以通过设置copyToOutputDirectory选项让其自动拷贝到xap包所在目录。

 

再来说引用的问题。

使用前置 / 引用资源时,SL会从当前Xap包中查找资源,找不到的话会到Xap包所在的目录查找 不使用前置 / 引用资源时,SL会从当前程序集内查找资源,如果找不着则会到Xap包所在目录查找其他选项你知道的话 你也可以使用/{程序集名};component/{图片资源路径}的方式来访问,这样就查找的路径就限定在程序集内部了,也就是那些标记为Resource的资源。

 

最后需要说的是,如果你的解决方案是有多个工程的,而且使用上面的路径还是抛出那个异常了,那么也不用太担心,基本上是路径的问题,可以尝试用“/{程序集名};component/{图片资源路径}”的方法来设置路径,比如我现在这个项目就可以这样设置“/TestControl;component/Assets/Styles.xaml”,这样一般不会有问题了,如果还有问题可能就是RP问题了。。。。

总结

以上是内存溢出为你收集整理的silverlight获取网页里的资源文件全部内容,希望文章能够帮你解决silverlight获取网页里的资源文件所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1077675.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存