精华内容
下载资源
问答
  • Portal Server 2.1 的动态主题定制

    千次阅读 2004-11-30 09:19:00
    首先,该系列将展示 WebSphere Portal Server 2.1 能够如何扩展以提供动态主题选择。然后,该系列将展示如何使用 IBM WebSphere Studio Application Developer 来快速开始所有 WebSphere Portal Server 开发活

    介绍

    这是介绍使用 IBM WebSphere® Portal Server 进行开发的系列文章的第一篇。首先,该系列将展示 WebSphere Portal Server 2.1 能够如何扩展以提供动态主题选择。然后,该系列将展示如何使用 IBM WebSphere Studio Application Developer 来快速开始所有 WebSphere Portal Server 开发活动。

    该系列的第 1 部分将介绍如何实现 Portal Server 的动态主题定制。第 2 部分将更详细地探讨使用 Application Developer 的 Portal Server 项目开发。我们将一步一步地指导您在 Application Developer 中创建 Portal Server 项目。第 3 部分将探讨如何设置 Application Developer 从而调试 Portal Server 应用程序和查找它们的故障。

    本文假定您已经安装了 WebSphere Portal Server 2.1 和 WebSphere Application Server 3.5.4。您还应该熟悉 Portal Server 和 Application Server 管理。要查看本文提供的项目源代码,您必须安装 WebSphere Studio Application Developer 4.0。

    WebSphere Portal Server

    WebSphere Portal Server 2.1 是一种能够在 IBM WebSphere Application Server 3.5.4 上托管聚集信息和协作应用程序的产品。Portal Server 通过 portlet 这种概念为站点用户提供了对多种信息和应用程序的单点访问。portlet 是可视的窗口,它将不同来源的内容组织到单独的界面供个人或群组访问。Portal Server 所使用的大部分底层技术都是基于 J2EE 规范的标准。Portlet 为向用户传送信息同时提供了可视的和编程的方法。因此,我们可以通过集成若干 portlet 从而快速构建企业门户网站,而这些 portlet 集成了 Portal Server 框架所提供的基础结构服务。所提供的大部分服务都可以通过一定的编程进一步定制。随着 WebSphere Portal Server 的普及,开发社区中越来越多的人开始有兴趣了解可用来加速开发过程的工具,并深入了解如何执行定制。

    图 1. 没有用户登录的 WebSphere Portal Server 缺省主页
    没有用户登录的 WebSphere Portal Server 缺省主页抓屏

    图 2. 用户 wpsadmin 登录之后的 WebSphere Portal Server
    用户 wpsadmin 登录之后的 WebSphere Portal Server 抓屏

    WebSphere Studio Application Developer

    WebSphere Studio Application Developer 为基于 Java™ 的软件开发提供了一种可扩展的集成开发环境。Application Developer 带有众多的插件,这些插件能缩短非常复杂的项目的开发周期。Application Developer 内建的功能和函数使其最适合开发 WebSphere Portal Server 项目。

    如果开发者选择了 VisualAge® for Java 作为开发平台,那么支持 WebSphere Portal Server 的开发和调试环境就是 WebSphere Portal Server Testing Environment。在撰写本文的时侯,Application Developer 带有内建的对 WebSphere Application Server 4.0 和 Tomcat 的开发支持。因为 Portal Server 建立在 WebSphere Application Server 3.5 之上,所以它没有对如何使用 Application Developer 进行 Portal Server 开发的直接参考。因此,“如何”使用 Application Developer 创建和管理 Portal Server 项目就变成了 Portal Server 开发者中的一个常见问题。要了解关于 WebSphere Portal Server Testing Environment 的更多信息,请访问 WebSphere Portal Server Support 页

    主题(Theme)和皮肤(Skin)

    WebSphere Portal Server 提供了一种易于定制门户网站的外观和感觉的方法。定制功能是通过主题(Theme)皮肤(Skin)的概念实现的。门户网站管理员或开发者可以通过为主题和皮肤创建所需的位图和 JSP™ 文件来决定站点的外观和感觉。WebSphere Portal Server 内含五种不同的主题和四种皮肤。可以使用的主题有:

    • DefaultTheme
    • GreyTheme
    • KhakiTheme
    • LilacTheme
    • TealTheme

    可以使用的皮肤有:

    • Album
    • Hint
    • Outline
    • Shadow

    主题决定横幅图像、选项卡图像、图标和门户网站的颜色方案(使用级联样式表实现),而皮肤则指定每个页面上每个 portlet 的外观和感觉。WebSphere PortalServer InfoCenter 的 Portal Modification 部分提供了关于主题和皮肤的文件位置的详细描述。InfoCenter 还提供了对如何应用不同位图方案的很好的描述,还有这些位图所需的大小和尺寸。为了说明起见,我们参考 InfoCenter,改编出下面的表 1。

    表 1. 关于 Default Theme 概要文件的位图

    资源类型 图像样本 注释
    横幅 banner.jpg 出现在横幅左上方的背景中
    导航图标 nav_customize.gif
    nav_customize.gif
    链接到定制门户网站的页面
    导航图标 nav_create_account.gif
    create_account.gif
    链接到自注册的页面
    导航图标 nav_forgot_password.gif
    nav_forgot_password.gif
    链接到帮助用户从站点管理员请求凭证的页面
    导航图标 nav_help.gif
    nav_help.gif
    链接到门户网站帮助页面
    导航图标 nav_login.gif
    nav_login.gif
    链接到登录页面
    导航图标 nav_logoff.gif
    nav_logoff.gif
    链接到注销页面
    导航图标 nav_profile.gif
    nav_profile.gif
    链接到更新帐户信息的页面
    选项卡一角 tab_left.gif
    tab_left.gif
    出现在选项卡左侧
    选项卡一角 tab_right.gif
    tab_right.gif
    出现在选项卡右侧
    Portlet 标题栏 title_back.gif
    title_back.gif
    将 portlet 从帮助模式返回到视图模式
    Portlet 标题栏 title_help.gif
    title_help.gif
    打开 portlet 帮助模式
    Portlet 标题栏 title_edit.gif
    title_edit.gif
    打开 portlet 编辑模式
    Portlet 标题栏 title_maximize.gif
    title_maximize.gif
    将 portlet 打开为最大化视图
    Portlet 标题栏 title_minimize.gif
    title_minimize.gif
    将 portlet 缩小为标题栏
    Portlet 标题栏 title_restore.gif
    title_restore.gif
    从最大化或最小化状态恢复 portlet

    对不同主题的选择可以通过修改 TurbineResources.Properties 文件的 theme.default 字段来激活。您可以在 <WPS_Install_Root>/app/web/WEB-INF/conf 文件夹中找到该属性文件的位置。

    图 3. TurbineResources.Properties 文件的目录位置
    展示 TurbineResources.Properties 文件的目录位置的抓屏

    当 WebSphere Portal Server 启动时,此文件被读取并解析,只要门户网站会话可用,theme.default 字段被指定的值就保持有效。

    另外,theme.default 字段不允许任何形式的键-值映射,这会导致单个主题被所有 Portal Server 用户会话使用。

    清单 1. TurbineResources.Properties 的片段

    # ...Some code truncated above... 
    #
    # This is the default theme to apply to the L&F
    #
    # Default: DefaultTheme
    
    theme.default=DefaultTheme
    
    # ...Some code truncated below... 

    这种缺省行为(即单个主题被所有 Portal Server 用户会话使用)在需要提供更好的粒度以定制 Portal Server 的用户界面时,将变成一种限制。通常,所需的粒度是下面环境参数的因素。

    • 用户会话(例如,登录用户标识)
    • 位置(例如,用户从哪里浏览,或用户的 IP 地址)
    • 时间(例如,是否为学校假期时间)

    动态主题选择

    当 WebSphere Portal Server 站点需要根据某个环境参数改变外观和感觉时,这个参数必须在运行时(可能是在作出对 Portal Server 的用户请求时)能够检索。举例来说,这种情况可能是,不同用户或不同用户组需要使用不同的颜色和位图的集合。对门户网站来说,根据用户喜好提供 UI 个性化是很常见的。有时候,选择逻辑的编程建立在公司策略之上,但更常见的是用户指定其喜好。根据主题选择的操作需求,实现动态主题选择所需的逻辑可能稍微有所不同。

    目前,WebSphere Portal Server 并不支持动态主题选择,因为在 TurbineResources.Properties 文件中,对于所有用户只有一个单独的 theme.default 字段被定义。幸运的是,只要作一些简单的编程,WebSphere Portal Server 就可以被扩展为处理动态主题选择。实现这些改变所需的步骤如下所示:

    1. 决定环境参数如何以及何时可以被检索。请参阅下载文件的 MyThemeTag.javagetEnvironParam() 的实现(下面提供了更多细节)。
    2. 使用环境参数作为到一个散列的键,从而派生出 Theme 值。请参阅下载文件的 MyThemeTag.javagetTheme() 的实现(下面提供了更多细节)。
    3. 分发 Theme 值。请参阅下载文件的 MyThemeTag.javadoStartTag() 的实现(下面提供了更多细节)。

    我将提供功能性框架代码来说明这些概念,从而详细描述上面的步骤 1 和步骤 3。至于步骤 2,从环境参数派生 Theme 值通常是特定于个别门户网站的。通常,这可以通过使用简单的查找表或从数据库表读取值来实现。现在,我们将通过使用一个每当 WebSphere Portal Server 启动时被初始化到内存中的散列表来展示。

    下一部分将描述如何扩展 Portal Server 以提供 UI 定制,这种定制允许使用扩展环境参数来影响主题选择。

    <wps:theme> 揭开秘密

    正如在前面部分提到过的,WebSphere Portal Server 中定义的每个主题都由一组用户界面实体或资源组成。Portal Server 开发者可以灵活地定制如图像、横幅和各种样式表(.css 文件)这些资源。这些样式表包含主题的颜色和字体类型方案。当 Portal Server 内核从 JSP 文件生成 HTML 代码时,对这些 .css 文件的引用就被插入,这样用户的浏览器就会从浏览器端查找这些样式表来定制页面。

    Portal Server 使用了 JSP 标记的概念来执行动态字段替换的任务。JSP 标记本质上有两个组件:一个使用 Java 代码实现的标记处理程序和一个 XML 标记元素。每当 JSP 文件中出现标记元素时,相关的标记处理程序 Java 代码就会被执行。Java 执行代码也会影响实际生成标记时标签的处理方式。

    WebSphere Portal Server 允许开发者实现和提供用户定义的定制标记库。这些用户定义的标记可以用于进一步加强 portlet 页面处理过程。除了开发者的定制标记库之外,Portal Server 还实现 Portal Server 引擎所使用的一套标记库函数。这被称为引擎标记库(Engine Tag Library)或 Engine.tld。您可以在 <WPS_Install_Root>/app/web/WEB-INF/tld 文件夹中找到该文件的位置。您可以在 WebSphere PortalServer InfoCenter 的 Changing the Portal layout 部分找到对每个引擎标记的功能的详细描述。

    图 4. Engine.tld 文件的目录位置
    展示 Engine.tld 文件的目录位置的抓屏

    如果您更仔细的研究 Engine.tld 文件,就会发现标记库的标记命令是如何被注册和声明的。

    清单 2. Engine.tld 的片段

    ...Some code truncated above...
    
    <tag>
       <name>url</name>
       <tagclass>com.ibm.wps.engine.tags.UrlTag</tagclass>
       <bodycontent>empty</bodycontent>
       <attribute>
          <name>type</name>
          <required>true</required>
       </attribute>
    </tag>
    
    ...Some code truncated below...

    请在引擎标记两端加入 <tag> 元素来声明它。<name> 元素将定义 JSP 文件中使用的标记元素名。<tagclass>元素标识 tag 元素的实现部分。<attribute> 标记中可以包括 JSP 标记的实现类所需的更多参数。

    清单 3. Engine.tld 中的主题标记注册

    ...Some code truncated above...
    
    <tag>
       <name>theme</name>
       <tagclass>com.ibm.wps.engine.tags.ThemeTag</tagclass>
       <bodycontent>empty</bodycontent>
    </tag>
    
    ...Some code truncated below... 

    由 WebSphere Portal Server 定义的主题标记不接受任何参数,主题标记处理程序的实现将返回主题的名称。返回的值将成为实际的文件,这个文件由 Portal Server 导出到它的 Web 文件夹中。举例来说,在 Banner.jsp 中使用 <wps:theme> 是这样的:

    清单 4. Banner.jsp 的片段

    // ...Some code truncated above...
    
    <TD class="wpsPortalBanner" valign="middle" align=left width="499" height=43
       background='<wps:url type="base"/>images/themes/<wps:theme/>/banner.jpg'>
    
    // ...Some code truncated below... 

    Banner.jsp 被编译并返回到用户的浏览器,就会生成下面的 HTML 代码:

    清单 5. 从 Banner.jsp 生成的 HTML 文件片段

    // ...Some code truncated above...
    
    <TD class="wpsPortalBanner" valign="middle" align=left width="499" height=43
       background='http://babylon5.sg.ibm.com/wps/
       portal/images/themes/TealTheme/banner.jpg'>
    
    // ...Some code truncated below... 

    根据 WebSphere Portal Server 服务器安装的位置和方式,JSP 标记引擎将用相关 URL 路径替换 <wps:url> 标记命令。<wps:theme> 标记被替换为 TurbineResources.Properties 文件的 theme.default 字段指定的 TealTheme 值。

    作出改变

    要实现动态主题选择,需要对 Portal Server 系统作出两处改动:

    • 修改 Engine.tld 来反映新的处理主题选择的 Java 代码。
    • 实现一个新的执行动态主题选择的 ThemeTag 类,并将其装入 Portal Server 实例。

    其实我们可以实现一个新的标记(例如 <mywps:dyna_theme>)并避免修改 Engine.tld 文件。这种方法的不好之处在于,您将必须在所有涉及到 Portal Server 使用的主题处理的 JSP 文件中添加这个新引入的标记。

    让我们使用更常用的方法 — 覆盖 Portal Server 提供的 ThemeTag 的原始行为。

    Engine.tld

    您需要对 Engine.tld 文件作出下面的改变。

    清单 6. Engine.tld 中要作出的改变

    <tag>
       <name>theme</name>
       <tagclass>com.ibm.etc.wps.tags.MyThemeTag</tagclass>
       <bodycontent>empty</bodycontent>
    </tag>

    请注意,我们使用自己的 com.ibm.etc.wps.tags.MyThemeTag 来替换 <tagclass> 中的 Java 类。这样做的效果是请求 Portal Server 的 JSP 处理器执行我们自己的主题标记处理程序。

    MyThemeTag.java

    MyThemeTag.java 类实现动态选择逻辑,它继承了 com.ibm.wps.engine.tags 包中原来的 ThemeTag 类。当标记处理程序代码被 JSP 处理器调用时,doStartTag() 方法将首先被调用。结果,环境参数通过 getEnvironParam() 方法获得。如果您要检索一个不同的环境参数,那么这就是您应该插入改变之处的地方。否则,代码会保持不变,并获取从 RunData 对象派生的用户登录标识。使用环境参数作为键,getTheme() 方法被调用以获取想要的主题值。我们的实现是要将用户标识的散列表与主题值匹配。在您的具体实现中,该字段可以被存储为 Portal Server 按用户喜好使用的关系数据库表的一部分,也可以从某种逻辑派生出来。更精巧的实现可能是从接受用户标识、IP 地址和日期/时间组的散列表检索主题值。这种形式的定制向 Portal 用户提供了更好的 UI 定制粒度。

    请参阅下面的下载文件以了解 MyThemeTag.java 的实现。

    运行改变

    下面的下载 ZIP 文件中,您会找到一个 mytheme.jar 项目的一个预先建立的版本、一个修改过的 engine.tld 文件和本文中出现的所有源代码。该项目创建时嵌入了所有所需的 JAR 文件。所以当您试图使用 Application Developer 重新编译时不会碰到任何丢失 JAR 文件的错误。我在本系列的第 2 部分将更详细地讨论 Portal Server 项目开发。

    如果您对使用 Application Developer 很熟悉,那么请继续将项目导入至工作区环境中,并开始构建代码。否则,只要将 mytheme.jar 文件复制到 <WPS_Install_Root>/app/web/WEB-INF/lib 目录中,并将 engine.tld 文件复制到 <WPS_Install_Root>/app/web/WEB-INF/tld 目录中。如果您愿意,请备份 engine.tld 文件。

    图 5. 向 Portal Server 类路径添加 mytheme.jar
    展示如何向 Portal Server 类路径添加 mytheme.jar 的抓屏

    接下来,请启动您的 WebSphere Application Server 管理控制台,然后将 mytheme.jar 路径添加到 Portal Server Web Application 的类路径中。这将确保 Portal Server 的 JSP 处理器能够定位新的主题标记处理程序。最后,请删除存储在 <WAS_Install_Root>/temp/default_host 目录中的任何缓存的门户网站页面副本。您可以安全地删除在该文件夹下找到的所有文件,因为它们通常是出于性能原因生成并缓存的。

    一旦作出了所有这些改变,请从 WebSphere Application Server 管理控制台重新启动 WebSphere Portal Server Application Server 查看所作的改变!

    图 6. 没有用户登录的 WebSphere Portal Server 缺省主页
    没有用户登录的 WebSphere Portal Server 缺省主页的抓屏

    图 7. 用户 wpsadmin 登录之后的 WebSphere Portal Server
    用户 wpsadmin 登录之后的 WebSphere Portal Server 的抓屏

    上面的图 1 和图 6 都展示了没有用户登录到 Portal Server 的缺省 WebSphere Portal Server 主页。请注意它们颜色方案的不同。在图 6 中,动态主题选择被触发,并为“guest”或没有用户标识的页面选择 GreyTheme。类似地,在图 7 中,登录的用户“wpsadmin”收到一个不同的主题 TealTheme(请将这与图 2 所示的缺省实现相比较)。这种不同组主题之间的切换是根据 MyThemeTag::doStartTag() 方法的实现动态发生的。请记住,TurbineResources.Properties 文件没有作任何改变,而且 WebSphere Portal Server Application Server 没有重新启动。

    总结

    本文和其中的代码展示了通过覆盖 Portal Server 类的缺省行为来扩展 WebSphere Portal Server 的可能性。使用覆盖标记处理程序缺省实现的相同原理,有很多不同的定制可以添加到一个高度个性化的门户网站的 Portal Server 中。举例来说,可以是覆盖 <wps:page> 标记处理程序并向每页的名称提供增值服务(例如国际化)。

    您还可以进一步扩展本文中所示的示例代码以提供定制器页,用于用户对主题选择(或其它类型的 UI 习惯选项)的请求,并向某种存储器(如数据库)持久存储值。

    最初对这种方法的实现是在 Portal Server 1.2 代码的基础之上开发的,因为撰写本文的原因,已经被移植到了 Portal Server 2.1 上。在 Portal Server 1.2 和 Portal Server 2.1 之间,标记引擎类工作的方式还有点小小的区别。如果您需要为使用 Portal Server 1.2 而设计的代码,请联系作者。

    相关参考

    展开全文
  • 本文教你如何让Silverlight 应用程序应用主题,并允许用户动态切换主题。 简介  从Silverlight工具包支持主题开始,就能实现该应用。但工具包2010年4月的版本和Silverlight 4中的新功能,使得更容易应用这些主题。...

    本教程将向您介绍如何让Silverlight应用程序应用主题,并允许用户动态切换
    (原文:http://weblogs.asp.net/lduveau/archive/2010/05/31/dynamically-apply-and-change-theme-with-the-silverlight-toolkit.aspx

    简介

    从Silverlight支持主题开始就能实现,但2010年4月以后的版本和Silverlight 4中的新特性,使得应用这些主题更加容易。

    您需要知道:

    • ImplicitStyleManager从工具箱中被删除了,这是因为现在在Silverlight 4已经支持隐式样式。
    • 该工具包包含一个主题控件,可以应用页面的主题控制。
    • 另外ContextMenuServiceContextMenu 控件可以允许用户在应用程序运行时进行主题切换。

    截至2010年4月从工具包中可用的主题:

     

     

    You could easily create your own, the XAML files used by those themes can be found on your local folder after installing the toolkit, for the April 2010 version the path is:这些主题所使用的XAML文件,您可以轻松地创建的,安装工具包后在您的本地文件夹可以找到,2010年4月版本的路径是:

    C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Toolkit\Apr10\Themes\Xaml

    入门

    如果没有它,安装最新版本的Silverlight工具包:
    http://silverlight.codeplex.com/http://silverlight.codeplex.com/

     

    然后打开Visual Studio 2010,创建新的Silverlight导航应用程序(或Silverlight商业应用程序)。

    添加Toolkit主题DLL

    右键单击Silverlight项目,选择“添加引用...”,然后选择NET选项卡中所有System.Windows.Controls.Toolkit .*的DLL。

     

    主题控件

    安装该工具包后,VS工具箱中会有一个主题控件,在MainPage.xaml页面Frame外面添加一个主题控件在这里,只想将主题应用到页面的内容部分。然后设置ThemeUri属性为其中引用的样式

     

    <toolkit:Theme x:Name="ThemeContainer" ThemeUri="/System.Windows.Controls.Theming.BubbleCreme;component/Theme.xaml">
    <toolkit:ContextMenuService.ContextMenu>
        <toolkit:ContextMenu>
            <toolkit:MenuItem Header="Theme" IsEnabled="False"/>
            <toolkit:Separator />            
            <toolkit:MenuItem Header="Default" />
                
            <toolkit:MenuItem Header="Bubble Creme"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="BubbleCreme"/>
    
            <toolkit:MenuItem Header="Bureau Black"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="BureauBlack"/>
    
            <toolkit:MenuItem Header="Bureau Blue"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="BureauBlue"/>
    
            <toolkit:MenuItem Header="Expression Dark"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="ExpressionDark"/>
    
            <toolkit:MenuItem Header="Expression Light"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="ExpressionLight"/>
    
            <toolkit:MenuItem Header="Rainier Orange"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="RainierOrange"/>
    
            <toolkit:MenuItem Header="Rainier Purple"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="RainierPurple"/>
    
            <toolkit:MenuItem Header="Shiny Blue"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="ShinyBlue"/>
    
            <toolkit:MenuItem Header="Shiny Red"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="ShinyRed"/>
    
            <toolkit:MenuItem Header="Whistler Blue"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="WhistlerBlue"/>
        </toolkit:ContextMenu>
    </toolkit:ContextMenuService.ContextMenu>
    


     

    
    

    如果你从工具箱拖放主题控件,Visual Studio会自动添加“工具包”的命名空间前缀,如果没有,需要在页面标题中手动添加:xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"

    在Home Page(/Views/Home.xaml)添加几个控件(TextBox, Button, Calendar, …),并在浏览器中测试您的应用程序,您应该看到在内容部分应用的主题:

    这就是,很容易。

    现在让我们为用户添加从列表中选择一个主题的功能。

    添加一个上下文菜单列出可用的主题

    在主题控件内的ContextMenuService添加一个ContextMenu控件(在运行时右键会出现):

    <toolkit:ContextMenuService.ContextMenu>
        <toolkit:ContextMenu>
            <toolkit:MenuItem Header="Theme" IsEnabled="False"/>
            <toolkit:Separator />            
            <toolkit:MenuItem Header="Default" />
                
            <toolkit:MenuItem Header="Bubble Creme"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="BubbleCreme"/>
    
            <toolkit:MenuItem Header="Bureau Black"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="BureauBlack"/>
    
            <toolkit:MenuItem Header="Bureau Blue"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="BureauBlue"/>
    
            <toolkit:MenuItem Header="Expression Dark"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="ExpressionDark"/>
    
            <toolkit:MenuItem Header="Expression Light"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="ExpressionLight"/>
    
            <toolkit:MenuItem Header="Rainier Orange"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="RainierOrange"/>
    
            <toolkit:MenuItem Header="Rainier Purple"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="RainierPurple"/>
    
            <toolkit:MenuItem Header="Shiny Blue"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="ShinyBlue"/>
    
            <toolkit:MenuItem Header="Shiny Red"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="ShinyRed"/>
    
            <toolkit:MenuItem Header="Whistler Blue"
                                Command="{StaticResource themeCommand}"
                                CommandParameter="WhistlerBlue"/>
        </toolkit:ContextMenu>
    </toolkit:ContextMenuService.ContextMenu>

    您需要添加一个引用这个DLL:
    System.Windows.Input.ToolkitSystem.Windows.Input.Toolkit 

    所以,现在你的页面的结构应该是:

    请注意,每个MenuItem被映射到一个命令,并且主题名称作为参数传递。

    你必须创建一个新类,并实现ICommand接口。这里的目标是获得一个主题控件的引用(按名称,但您可能会找到更好的办法做到这一点),并设置其ThemeUri属性。

     

    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Markup;
    using System.IO;
    using System.Windows.Controls.Theming;
    
    namespace FunWithThemes
    {
    
        public class ThemeChangeCommand : ICommand
        {
            #region ICommand Members
    
            public bool CanExecute(object parameter)
            {
                return true;
            }
    
            public event EventHandler CanExecuteChanged;
    
            public void Execute(object parameter)
            {
                Theme themeContainer = (Theme)((FrameworkElement)Application.Current.RootVisual).FindName("ThemeContainer");
    
                string themeName = parameter as string;
    
    
                if (themeName == null)
                {
                    themeContainer.ThemeUri = null;
                }
                else 
                {
                    themeContainer.ThemeUri = new Uri("/System.Windows.Controls.Theming." + themeName + ";component/Theme.xaml", UriKind.RelativeOrAbsolute);
                }
    
                if (CanExecuteChanged != null)
                    CanExecuteChanged(this, new EventArgs());
            }
    
            #endregion
        }
    }
    
    


     

    如果使用“Silverlight的商业应用程序”模板,你应该改变类似

     Theme themeContainer = (Theme)((FrameworkElement)((ContentControl)Application.Current.RootVisual).Content).FindName( "ThemeContainer" ); 
    在MainPage.xaml中(或在应用程序资源)的资源中添加命令:
     < Grid.Resources > 
         < local:ThemeChangeCommand x:Key ="themeCommand" />
     </ Grid.Resources > 

    "local"是应用程序的命名空间前缀

    测试!

    现在,当您运行测试页,你可以用鼠标右键单击并选择一个主题:

    选择主题“Shiny Red”:

    或 “Bureau Blue”:

    您有多种存储策略(独立存储,服务器配置文件,甚至Cookies,... ...)

     

    
    
    展开全文
  • 动态URL是什么 动态URL就是动态页面,动态链接,即指在URL中出现“?”这样的参数符号,并以aspx、asp、jsp、php、perl、cgi为后缀的url。 动态URL有什么特点 1、在建设反向链接过程中,因为动态URL的非永久性,所以...

    动态URL是什么
    动态URL就是动态页面,动态链接,即指在URL中出现“?”这样的参数符号,并以aspx、asp、jsp、php、perl、cgi为后缀的url。

    动态URL有什么特点
    1、在建设反向链接过程中,因为动态URL的非永久性,所以它不如静态URL有优势。

    2、动态URL较之静态的URL不利于搜索引擎抓取。

    3、动态网址的生成是采集数据库的内容,所以不能保证网页内容的稳定性和链接的永久性,所以很难被搜索引擎收录快照。
    动态URL的优点
    1、同一类型网页用相同的URL类型,仅调用参数不同。比如列表页和文章页,这样方便管理,且能知道网页的类型是列表页还是内容页。

    2、动态URL中的参数对搜索引擎有提示作用。搜索引擎抓取网页时更容易理解网页的主题,就像URL中含有关键词一样。搜索引擎对后的参数有识别能力,有利于网页的关键词排名。

    3、网站物理结构扁平化。网页都使用相同的页面进行调用,页面最多有两层目录结构,便于管理和提高处理速度。

    动态URL的缺点
    1、动态URL相对不易传播,用户对于过多的参数都是比较反感的,在站外进行传播的时候,用户信任度会比静态URL低。

    搜索引擎中,动态URL的信任度也会比静态URL略低一点,因为动态URL的变动性较大,不如静态URL稳定。

    2、动态URL中的参数可能使搜索引擎蜘蛛陷入无限循环的爬行中,造成巨大搜索引擎和服务器资源浪费。

    搜索引擎一般对动态URL不够信任,从而使很多动态URL的网页不能被收录。

    3、动态URL中的参数如果顺序调换,或者网页设有访问SessionID,这些相同的网页会被认为是不同的页面。

    会导致搜索引擎认为,网站上存在很多重复内容,有可能影响正常网页的收录和排名,甚至被误惩罚。所以做SEO最好还是做静态URL。

    展开全文
  • sencha ext js 动态更换皮肤 主题

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/42016107

    本文作者:sushengmiyan

    ------------------------------------------------------------------------------------------------------------------------------------

    为方便起见,使用sencha cmd创建一个工程,使用app build命令build工程,使用web start命令启动服务。


    好了,现在更改下main.js中的一点代码,增加如下内容到panel中:

    ,{
            xtype: 'combo',
            width: '100',
    		labelWidth: '40',
    		fieldLabel: 'Theme',
    		displayField: 'name',
    		valueField: 'value',
    		//labelStyle: 'cursor:move;',
    		//margin: '5 5 5 5',
    		queryMode: 'local',
    		store: Ext.create('Ext.data.Store', {
    			fields: ['value', 'name'],
    			data : [
    				{ value: 'neptune', name: 'Neptune主题' },
    				{ value: 'neptune-touch', name: 'Neptune Touch主题' },
    				{ value: 'crisp', name: 'Crisp主题' },
    				{ value: 'crisp-touch', name: 'Crisp Touch主题' },
    				{ value: 'classic', name: 'Classic主题' },
    				{ value: 'gray', name: 'Gray主题' }
    			]
    		}),
    		//value: theme,
    		listeners: {
    			select: function(combo) {
    				var  theme = combo.getValue();
    				var	href = 'ext/packages/ext-theme-'+theme+'/build/resources/ext-theme-'+theme+'-all.css';
    				var	link = Ext.fly('theme');
    			 
    				if(!link) {
    					link = Ext.getHead().appendChild({
    						 tag:'link',
    						 id:'theme',
    						 rel:'stylesheet',
    						 href:''
    					});
    				};
    				link.set({href:Ext.String.format(href, theme)});
    			}
    		}
        }

    main.js代码应该如下所示:(完整内容)

    /**
     * This class is the main view for the application. It is specified in app.js as the
     * "autoCreateViewport" property. That setting automatically applies the "viewport"
     * plugin to promote that instance of this class to the body element.
     *
     * TODO - Replace this content of this view to suite the needs of your application.
     */
    Ext.define('oaSystem.view.main.Main', {
        extend: 'Ext.container.Container',
        requires: [
            'oaSystem.view.main.MainController',
            'oaSystem.view.main.MainModel'
        ],
    
        xtype: 'app-main',
        
        controller: 'main',
        viewModel: {
            type: 'main'
        },
    
        layout: {
            type: 'border'
        },
    
        items: [{
            xtype: 'panel',
            bind: {
                title: '{name}'
            },
            region: 'west',
            html: '<ul><li>This area is commonly used for navigation, for example, using a "tree" component.</li></ul>',
            width: 250,
            split: true,
            tbar: [{
                text: 'Button',
                handler: 'onClickButton'
            },{
            xtype: 'combo',
            width: '100',
    		labelWidth: '40',
    		fieldLabel: 'Theme',
    		displayField: 'name',
    		valueField: 'value',
    		//labelStyle: 'cursor:move;',
    		//margin: '5 5 5 5',
    		queryMode: 'local',
    		store: Ext.create('Ext.data.Store', {
    			fields: ['value', 'name'],
    			data : [
    				{ value: 'neptune', name: 'Neptune主题' },
    				{ value: 'neptune-touch', name: 'Neptune Touch主题' },
    				{ value: 'crisp', name: 'Crisp主题' },
    				{ value: 'crisp-touch', name: 'Crisp Touch主题' },
    				{ value: 'classic', name: 'Classic主题' },
    				{ value: 'gray', name: 'Gray主题' }
    			]
    		}),
    		//value: theme,
    		listeners: {
    			select: function(combo) {
    				var  theme = combo.getValue();
    				var	href = 'ext/packages/ext-theme-'+theme+'/build/resources/ext-theme-'+theme+'-all.css';
    				var	link = Ext.fly('theme');
    			 
    				if(!link) {
    					link = Ext.getHead().appendChild({
    						 tag:'link',
    						 id:'theme',
    						 rel:'stylesheet',
    						 href:''
    					});
    				};
    				link.set({href:Ext.String.format(href, theme)});
    			}
    		}
        }]
        },{
            region: 'center',
            xtype: 'tabpanel',
            items:[{
                title: 'Tab 1',
                html: '<h2>Content appropriate for the current navigation.</h2>'
            }]
        }]
    });
    

    纠结了很久的问题终于释怀了。之前看的都是使用swapstylesheet我一直么有成功过。偶尔看的了这篇文章,觉得不错,果真成功了。

    http://extjs.eu/lightweight-theming/

    推荐一下,这个网站,内容比较充实,界面也比较好看。就是有些插件需要花钱购买。

    展开全文
  • SQL Server服务器级别的动态管理视图

    千次阅读 2011-03-04 09:53:00
     动态管理视图是SQL Server的一个功能,用于提供详细的数据库和系统信息。第一类的DMVs,正如我在第一篇文章“深入了解SQL Server动态管理视图”中所指出的是针对数据库级别的。另一类DMV是针对服务器级别的...
  • kafka动态指定主题与分组ID 原因 近期项目新做了一个环境,采购了阿里的CLB进行四层代理的负载均衡,每个服务都搭建了两个实例,后来测试过程中,遇到了一个问题,推送服务有时没数据 问题描述 两个相同实例,都作为...
  • 一个页面要显示不同的主题风格,就需要写不同的css文件; 在做不同css文件相互切换时,首先要了解link标签中的rel属性; rel属性值: alternate文档的替代版本(比如打印页、翻译或镜像)。 stylesheet 文档的外部...
  • 1   众里寻他千百度 ...小崔已经领会了动态图层服务的要点,忍不住感叹: “这个真是一个神奇的服务啊!”说完两人相视一笑…… 感谢yelloweast童鞋的辛勤撰写,把技术文章写成这样,有才银!
  • 引用: Zhang Y, Qian Y, Wang Y. A RecommendationAlgorithm Based on Dynamic User Preference and Service Quality[C]//2018 IEEEInternational Conference on Web Services (ICWS)....在服务计算领域...
  • 最近由于在项目中要实现动态插值分析,于是通过在网上大量查阅,借鉴前辈们的工作... 首先,要在Web上实现动态插值分析,就不得不提到GP Service(地理处理服务),据ArcGIS Help中提到的概念,地理处理服务是借助于
  • 一个页面要显示不同的主题风格,就需要写不同的css文件; 在做不同css文件相互切换时,首先要了解link标签中的rel属性; rel属性值: alternate文档的替代版本(比如打印页、翻译或镜像)。 stylesheet 文档的...
  • 有强迫症的我要支持网易云跟帖,所以必须要更新一个NEXT主题,原来的主题版本有点旧,没有集成网易云跟帖,所以又来重新折腾了折腾~绑定域名绑定域名的思路如下: 在万网购买自己喜欢的域名(.com的会贵一点,.site...
  • 在新版本Kafka中,__consumer_offsets这个topic是存放消费者偏移量的,但是该主题默认配置副本数量只有1,容易造成单点故障,我们可以动态修改(无需重启服务)副本因子,提高kafka的可靠性   修改流程 --------...
  • 整合spring-integration-mqtt,连接多个mqtt mqtt整合 添加依赖 添加配置 工具类说明 订阅消息 发送消息 mqtt整合 最近有一个业务,要求连接多个非集群不同的mqtt服务,于是乎写了一个可根据配置动态配置的工具。...
  • 静态代理和动态代理简介

    千次阅读 2017-07-14 15:49:19
    代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务。 代理模式的角色分为: 主题接口: 即代理类的所实现的行为接口
  • Android自定义动态壁纸开发

    万次阅读 多人点赞 2019-01-06 18:35:47
    动态壁纸的本质其实就是一个服务在维护一个动态壁纸引擎Engine,所以我们看到的动态效果其实是通过这个引擎画出来的。而维护这个引擎的服务,就是WallpaperService。本篇文章并不讨论内部实现原理...
  • Niu主题一款由高时银博客开发制作的营销型wordpress企业主题,所谓营销型wordpress企业主题,不仅为企业展示相关的企业文化介绍,还要为企业的产品或服务做相应的推广宣传,适合所有类型的企业单位,如:制造类企业...
  • 内容提要:本文概要地论述了动态口令(动态...主题词:信息安全、身份认证、动态口令 动态口令的概念与起源  身份认证是信息安全体系的重要组成部分,它是保护信息系统安全的第一道大门。它的任务是检验信息系统用户
  • ZooKeeper动态重新配置

    千次阅读 2019-01-23 14:35:00
    ZooKeeper动态重新配置 概观 配置格式的更改 指定客户端端口 standaloneEnabled标志 reconfigEnabled标志 动态配置文件 向后兼容性 升级到3.5.0 动态重新配置ZooKeeper集合 API 安全 检索当前的...
  • Android插件化方式实现View动态更新

    千次阅读 2016-12-20 12:48:36
    大家可以想一个问题:假设我们App首页有个Icon,用来根据不同的节日播放不同主题的音乐,例如:圣诞节,需要把Icon变成圣诞老人,并且播放圣诞主题的音乐,春节,需要把Icon变成鞭炮,并且播放春节喜庆的音乐。...
  • ng-zorro自定义主题

    千次阅读 2019-03-10 10:50:08
    要给现有使用ng-zorro框架的前端项目添加自定义主题,首先将整个前端源码备份。在项目目录下,执行命令行: ng add ng-zorro-antd --theme 重新下载ng-zorro-antd后,用ng serve命令启动服务,发现编译错误。找到...
  • 什么是Web?及web服务器原理

    千次阅读 2016-12-10 23:53:06
    什么是Web? Web就是一种超文本信息系统,Web的一个主要的概念就是超文本连接,它使得文本不再象一本书一样是固定的线性的。而是可以从一个位置跳到另外的位置。你可以从中获取更多的信息。可以转到别的主题上。...
  • Hexo-Matery主题细致美化

    万次阅读 2021-01-21 20:39:03
    Hexo-Matery主题美化 在一番瞎改js代码后,终于无法忍受next主题,于是愤然投入Matery大家庭,结果证明,香! 下面是我记录的配置Matery主题的流程,仅供后来的师傅们参考。 大家可以来我Hexo博客主页看看具体效果...
  • LNMP架构动态网页

    千次阅读 2020-11-07 10:35:10
    LNMP架构一种常用的用来搭建动态网站页面的架构。 L:代表Linux系统;即LNMP架构是在Linux系统上实现的。若是第一次学习部署动态网页的话,最好把selinux和防火墙都关闭 N:代表nginx服务;ngnix服务主要用于处理...
  • Mqtt入门之主题主题过滤器

    千次阅读 2017-11-28 10:52:09
    主题Topic 主题是一个UTF-8字符串,由一个或多个主题级别组成, 每个主题级别之间由正斜杠(主题级别分隔符)分隔,如下图所示: 主题过滤器TopicFilter 含有通配符的主题,目的是让客户端同时订阅多个主题。...
  • 相信动态列的实现困扰了很多人,大数据量,多字段的加载将会非常耗时,数据又做不到真正的动态灵活。现有的方式都是通过变向的隐藏等方式来实现。
  • 我是不是都要演示我的Spotifinder Ext ...今年,我在SenchaCon展示了高级主题功能,并收到了一些关于如何创建Spotifinder应用程序主题的咨询。因此,我觉得编写一个教程来说明如何创建这个相当酷,且很好看的暗黑主题
  • 代理模式 代理模式(Proxy Pattern),又叫委托模式,是指为其他对象提供一种代理,以控制对这...代理角色-Proxy:把所有抽象主题角色定义的方法限制委托给具体主题角色实现,并且在具体主题角色处理完毕前后做预处...
  • Java代理和动态代理机制分析和应用

    千次阅读 2015-12-02 19:54:54
    本博文中项目代码已开源下载地址:GitHubJava代理和动态代理机制分析和应用概述代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个...主题接口:定义代理类和真实主题的公共对外方法,也是代理

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 105,457
精华内容 42,182
关键字:

动态主题服务什么