<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_liulun</title><subtitle type="text">专注！坚持！</subtitle><id>http://feed.cnblogs.com/blog/u/32486/rss</id><updated>2012-06-02T00:55:54Z</updated><author><name>liulun</name><uri>http://www.cnblogs.com/liulun/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/liulun/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/32486/rss"/><entry><id>http://www.cnblogs.com/liulun/archive/2012/05/29/2523934.html</id><title type="text">使用jstree创建无限分级的树(ajax动态创建子节点)</title><summary type="text">首先来看一下效果页面加载之初节点全部展开后首先数据库的表结构如下其中Id为主键,PId为关联到自身的外键两个字段均为GUID形式层级关系主要靠这两个字段维护其次需要有一个类型 public class MenuType { public Guid Id { get; set; } public Guid PId { get; set; } public string MenuName { get; set; } public string Url { get; set; } public int OrderNum...</summary><published>2012-05-29T06:30:00Z</published><updated>2012-05-29T06:30:00Z</updated><author><name>liulun</name><uri>http://www.cnblogs.com/liulun/</uri></author><link rel="alternate" href="http://www.cnblogs.com/liulun/archive/2012/05/29/2523934.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/liulun/archive/2012/05/29/2523934.html"/><content type="html">&lt;p&gt;首先来看一下效果&lt;/p&gt;&lt;p&gt;页面加载之初&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201205/201205291430245681.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201205/201205291430247841.png" alt="image" width="292" height="208" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;节点全部展开后&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201205/201205291430241188.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201205/201205291430247808.png" alt="image" width="306" height="282" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;首先数据库的表结构如下&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201205/201205291430247251.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201205/20120529143025283.png" alt="image" width="379" height="183" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;其中Id为主键,PId为关联到自身的外键&lt;/p&gt;&lt;p&gt;两个字段均为GUID形式&lt;/p&gt;&lt;p&gt;层级关系主要靠这两个字段维护&lt;/p&gt;&lt;p&gt;其次需要有一个类型&lt;/p&gt;&lt;fieldset style="background-color: #e0eff6; width: 900px; color: #15428b;"&gt;    public class MenuType&lt;br/&gt;    {&lt;br/&gt;        public Guid Id { get; set; }&lt;br/&gt;        public Guid PId { get; set; }&lt;br/&gt;        public string MenuName { get; set; }&lt;br/&gt;        public string Url { get; set; }&lt;br/&gt;        public int OrderNum { get; set; }&lt;br/&gt;        public int SonCount { get; set; }&lt;br/&gt;    }&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;/fieldset&gt;&lt;p&gt;此类型比数据库表增加了一个属性&lt;/p&gt;&lt;p&gt;SonCount&lt;/p&gt;&lt;p&gt;这个属性用来记录当前节点的子节点的个数&lt;/p&gt;&lt;p&gt;注意：也可以把此属性放在数据库中，性能上会提升一些，但需要增加额外的代码来维护此字段&lt;/p&gt;&lt;p&gt;接下来看一下取数据的方式&lt;/p&gt;&lt;fieldset style="background-color: #e0eff6; width: 900px; color: #15428b;"&gt;        protected void Page_Load(object sender, EventArgs e)&lt;br/&gt;        {&lt;br/&gt;            if (Request["Action"] == "AJAX")&lt;br/&gt;            {&lt;br/&gt;                var result = GetMenu(Request["pid"]);&lt;br/&gt;                JavaScriptSerializer serializer = new JavaScriptSerializer();&lt;br/&gt;                string sRet = serializer.Serialize(result);&lt;br/&gt;                Response.Write(sRet);&lt;br/&gt;                Response.End();&lt;br/&gt;            }&lt;br/&gt;        }&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;/fieldset&gt;&lt;p&gt;页面加载之初判断是否需要获取菜单数据&lt;/p&gt;&lt;p&gt;其中请求参数pid为客户端需要获取的节点ID&lt;/p&gt;&lt;p&gt;如果请求顶级节点，则此参数的值为00000000-0000-0000-0000-000000000000&lt;/p&gt;&lt;p&gt;GetMenu函数获取需要请求的节点数据&lt;/p&gt;&lt;fieldset style="background-color: #e0eff6; width: 900px; color: #15428b;"&gt;        private List&amp;lt;MenuType&amp;gt; GetMenu(string pid)&lt;br/&gt;        {&lt;br/&gt;            var result = new List&amp;lt;MenuType&amp;gt;();&lt;br/&gt;            SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=SHU;User ID=sa;Password=allen;");&lt;br/&gt;            conn.Open();&lt;br/&gt;            SqlCommand cmd = new SqlCommand();&lt;br/&gt;            cmd.Connection = conn;&lt;br/&gt;            cmd.CommandText = "select a.*,b.cout as count from Menu a left join (select COUNT(*) as cout,Menu.PId from Menu group by Menu.PId) as b on a.Id = b.PId  where a.PId = '" + pid + "' order by OrderNum";&lt;br/&gt;            SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);&lt;br/&gt;            while (dr.Read())&lt;br/&gt;            {&lt;br/&gt;                var obj = new MenuType();&lt;br/&gt;                obj.Id =Guid.Parse(dr["Id"].ToString());&lt;br/&gt;                obj.MenuName = dr["MenuName"].ToString();&lt;br/&gt;                obj.OrderNum = Convert.ToInt32(dr["OrderNum"]);&lt;br/&gt;                obj.PId = dr["PId"] == DBNull.Value ? Guid.Empty : Guid.Parse(dr["PId"].ToString());&lt;br/&gt;                obj.Url = dr["Url"].ToString();&lt;br/&gt;                obj.SonCount = dr["count"] == DBNull.Value ? 0 : Convert.ToInt32(dr["count"]);&lt;br/&gt;                result.Add(obj);&lt;br/&gt;            }&lt;br/&gt;            return result;&lt;br/&gt;        }&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;/fieldset&gt;&lt;p&gt;在本DEMO中使用JavaScriptSerializer来序列化菜单数组&lt;/p&gt;&lt;p&gt;前台的代码如下&lt;/p&gt;&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding:10px;"&gt;&amp;lt;asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent"&amp;gt;&lt;br/&gt;    &amp;lt;link href="Scripts/themes/default/style.css" rel="stylesheet" type="text/css" /&amp;gt;&lt;br/&gt;    &amp;lt;script src="Scripts/jquery.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;&lt;br/&gt;    &amp;lt;script src="Scripts/jquery.jstree.js" type="text/javascript"&amp;gt;&amp;lt;/script&amp;gt;&lt;br/&gt;    &amp;lt;script&amp;gt;&lt;br/&gt;        $(function () {&lt;br/&gt;            $.getJSON("/default.aspx?ACTION=AJAX&amp;amp;pid=00000000-0000-0000-0000-000000000000", function (result) {&lt;br/&gt;                $.each(result, function (i, item) {&lt;br/&gt;                    var typeN = item.SonCount &amp;gt; 0 ? "jstree-closed" : "jstree-leaf";&lt;br/&gt;                    $("#tree").append("&amp;lt;li id='phtml_" + item.Id + "' class='" + typeN + "'&amp;gt;&amp;lt;a href='#'&amp;gt;" + item.MenuName + "&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;");&lt;br/&gt;                });&lt;br/&gt;                $("#demo2").jstree({&lt;br/&gt;                    "plugins": ["themes", "html_data", 'types', "ui", "checkbox"],&lt;br/&gt;                    'core': { 'animation': 0 },&lt;br/&gt;                    "types": { "types":&lt;br/&gt;                                {&lt;br/&gt;                                    "person": { "icon": { "image": "/Scripts/themes/default/person.png"} },&lt;br/&gt;                                    "depar2": { "icon": { "image": "/Scripts/themes/default/depar2.png"} },&lt;br/&gt;                                    "default": { "icon": { "image": "/Scripts/themes/default/depar1.png"} }&lt;br/&gt;                                }&lt;br/&gt;                    }&lt;br/&gt;                }).bind("open_node.jstree", function (e, data) {&lt;br/&gt;                    var id = data.rslt.obj[0].id;&lt;br/&gt;                    if ($("#" + id + " li").length &amp;gt; 0) { return; }&lt;br/&gt;                    $.getJSON("/default.aspx?ACTION=AJAX&amp;amp;pid=" + id.replace("phtml_", ""), function (result) {&lt;br/&gt;                        var str = "&amp;lt;ul&amp;gt;"&lt;br/&gt;                        $.each(result, function (i, item) {&lt;br/&gt;                            var typeN = item.SonCount &amp;gt; 0 ? "jstree-closed" : "jstree-leaf";&lt;br/&gt;                            var icon = item.SonCount &amp;gt; 0 ? "depar2" : "person";&lt;br/&gt;                            str += "&amp;lt;li rel = '" + icon + "' id='phtml_" + item.Id + "' class='" + typeN + "'&amp;gt;&amp;lt;a  href='#'&amp;gt; " + item.MenuName + "&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;";&lt;br/&gt;                        });&lt;br/&gt;                        str += "&amp;lt;/ul&amp;gt;";&lt;br/&gt;                        $("#" + id).append(str);&lt;br/&gt;                        var tree = jQuery.jstree._reference("#" + id);&lt;br/&gt;                        tree.refresh();&lt;br/&gt;                        $("ins[class='jstree-checkbox jstree-icon']").removeClass("jstree-icon");&lt;br/&gt;                        $(".jstree-checkbox").attr("style", "");&lt;br/&gt;                    });&lt;br/&gt;                });&lt;br/&gt;            });&lt;br/&gt;        });&lt;br/&gt;&lt;br/&gt;    &amp;lt;/script&amp;gt;&lt;br/&gt;&amp;lt;/asp:Content&amp;gt;&lt;br/&gt;&amp;lt;asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent"&amp;gt;&lt;br/&gt;    &amp;lt;div id="demo2"&amp;gt;&lt;br/&gt;    &amp;lt;ul id="tree"&amp;gt;&lt;br/&gt;    &amp;lt;/ul&amp;gt;&lt;br/&gt;    &amp;lt;/div&amp;gt;&lt;br/&gt;&amp;lt;/asp:Content&amp;gt;&lt;br/&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;页面加载之初，先请求顶级节点&lt;/p&gt;&lt;p&gt;如果顶级节点的SonCount属性大于0&lt;/p&gt;&lt;p&gt;则使节点为闭合状态（样式为jstree-closed）&lt;/p&gt;&lt;p&gt;如果节点无子节点&lt;/p&gt;&lt;p&gt;则该节点的样式为jstree-leaf&lt;/p&gt;&lt;p&gt;当用户点击闭合状态的节点时，客户端发起请求&lt;/p&gt;&lt;p&gt;并把点击节点的ID传给后端，后端获取到点击节点的子节点后&lt;/p&gt;&lt;p&gt;通过append添加到点击节点下&lt;/p&gt;&lt;p&gt;至此，无限分级的树创建完成&lt;/p&gt;&lt;p&gt;其中不包含数据库&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;---------------------------------------------------------------------------&lt;/p&gt;&lt;p&gt;喜欢本文的，请点支持，有问题请在本文下评论，我会及时回复的&lt;/p&gt;&lt;p&gt;谢谢大家&lt;/p&gt;&lt;img src="http://www.cnblogs.com/liulun/aggbug/2523934.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/liulun/archive/2012/05/29/2523934.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/liulun/archive/2012/05/18/2507472.html</id><title type="text">使用Raphael绘制流程图，自绘动态箭头，可拖动，有双击事件，纯前端，兼容各种浏览器</title><summary type="text">关于Raphaël Raphaël是一个在网页上绘图的js类库，非常小压缩版只有89k左右 官方宣称兼容各种主流浏览器，据笔者测试在IE6下尚有一些问题（不过这些与本文无关） 他是使用js来创建vml或svg来绘图的 缘起 项目中不能使用Silverlight或者flash来解决绘图和拖动的问题 而且为了项目效果较好，要求拖动的时候箭头能动态改变起点和重点，别且箭头要改变方向 所以只能考虑JS了 ...</summary><published>2012-05-18T03:17:00Z</published><updated>2012-05-18T03:17:00Z</updated><author><name>liulun</name><uri>http://www.cnblogs.com/liulun/</uri></author><link rel="alternate" href="http://www.cnblogs.com/liulun/archive/2012/05/18/2507472.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/liulun/archive/2012/05/18/2507472.html"/><content type="html">&lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;关于Raphaël&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Raphaël是一个在网页上绘图的js类库，非常小压缩版只有89k左右&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="4"&gt;官方宣称兼容各种主流浏览器，据笔者测试在IE6下尚有一些问题（不过这些与本文无关）&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="4"&gt;他是使用js来创建vml或svg来绘图的&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#ff0000" size="4"&gt;&lt;strong&gt;缘起&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#000000" size="4"&gt;项目中不能使用Silverlight或者flash来解决绘图和拖动的问题&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font size="4"&gt;而且为了项目效果较好，要求拖动的时候箭头能动态改变起点和重点，别且箭头要改变方向&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#000000" size="4"&gt;所以只能考虑JS了&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#ff0000" size="4"&gt;&lt;strong&gt;效果&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201205/201205181116589684.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201205/201205181116584667.png" width="411" height="201"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000" size="4"&gt;演示&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.mrlh.net/flowchart/demo.htm"&gt;http://www.mrlh.net/flowchart/demo.htm&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#ff0000" size="4"&gt;&lt;strong&gt;源码&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#000000" size="3"&gt;引用&lt;/font&gt;&lt;/p&gt; &lt;fieldset style="background-color: #e0eff6; width: 900px; color: #15428b"&gt;    &amp;lt;script language="javascript" type="text/javascript" src="raphael.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br/&gt;    &amp;lt;script language="javascript" type="text/javascript" src="jquery.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;div&gt;&lt;/div&gt;&lt;/fieldset&gt;&lt;p&gt;这两个东西是不相干的，引用先后顺序也无所谓&lt;/p&gt;&lt;p&gt;页面加载完成后的代码&lt;/p&gt;&lt;fieldset style="background-color: #e0eff6; width: 900px; color: #15428b"&gt;        $(function () {&lt;br/&gt;            //用来存储节点的顺序&lt;br/&gt;            var connections = [];&lt;br/&gt;            //拖动节点开始时的事件&lt;br/&gt;            var dragger = function () {&lt;br/&gt;                this.ox = this.attr("x");&lt;br/&gt;                this.oy = this.attr("y");&lt;br/&gt;                this.animate({ "fill-opacity": .2 }, 500);&lt;br/&gt;            };&lt;br/&gt;            //拖动事件&lt;br/&gt;            var move = function (dx, dy) {&lt;br/&gt;                var att = { x: this.ox + dx, y: this.oy + dy };&lt;br/&gt;                this.attr(att);&lt;br/&gt;                $("#test" + this.id).offset({ top: this.oy + dy + 10, left: this.ox + dx + 10 });&lt;br/&gt;                for (var i = connections.length; i--; ) {&lt;br/&gt;                    r.drawArr(connections[i]);&lt;br/&gt;                }&lt;br/&gt;            };&lt;br/&gt;            //拖动结束后的事件&lt;br/&gt;            var up = function () {&lt;br/&gt;                this.animate({ "fill-opacity": 0 }, 500);&lt;br/&gt;            };&lt;br/&gt;            //创建绘图对象&lt;br/&gt;            var r = Raphael("holder", $(window).width(), $(window).height());&lt;br/&gt;            //绘制节点&lt;br/&gt;            var shapes = [&lt;br/&gt;                        r.rect(190, 100, 60, 40, 4),&lt;br/&gt;                        r.rect(290, 80, 60, 40, 4),&lt;br/&gt;                        r.rect(290, 180, 60, 40, 4),&lt;br/&gt;                        r.rect(450, 100, 60, 40, 4)&lt;br/&gt;                     ];&lt;br/&gt;            //定位节点上的文字&lt;br/&gt;            $("#test1").offset({ top: 100 + 10, left: 190 + 10 });&lt;br/&gt;            $("#test2").offset({ top: 80 + 10, left: 290 + 10 });&lt;br/&gt;            $("#test3").offset({ top: 180 + 10, left: 290 + 10 });&lt;br/&gt;            $("#test4").offset({ top: 100 + 10, left: 450 + 10 });&lt;br/&gt;            //为节点添加样式和事件，并且绘制节点之间的箭头&lt;br/&gt;            for (var i = 0, ii = shapes.length; i &amp;lt; ii; i++) {&lt;br/&gt;                var color = Raphael.getColor();&lt;br/&gt;                shapes[i].attr({ fill: color, stroke: color, "fill-opacity": 0, "stroke-width": 2, cursor: "move" });&lt;br/&gt;                shapes[i].id = i + 1;&lt;br/&gt;                shapes[i].drag(move, dragger, up);&lt;br/&gt;                shapes[i].dblclick(function () { alert(this.id) })&lt;br/&gt;            }&lt;br/&gt;            //存储节点间的顺序&lt;br/&gt;            connections.push(r.drawArr({ obj1: shapes[0], obj2: shapes[1] }));&lt;br/&gt;            connections.push(r.drawArr({ obj1: shapes[1], obj2: shapes[2] }));&lt;br/&gt;            connections.push(r.drawArr({ obj1: shapes[2], obj2: shapes[3] }));&lt;br/&gt;        });&lt;div&gt;&lt;/div&gt;&lt;/fieldset&gt;&lt;p&gt;这些代码注释比较详细，就不多说了&lt;/p&gt;&lt;p&gt;在这些代码中涉及到操作的界面元素HTML代码如下&lt;/p&gt;&lt;fieldset style="background-color: #e0eff6; width: 900px; color: #15428b"&gt;&amp;lt;body&amp;gt;&lt;br/&gt;    &amp;lt;div id="holder"&amp;gt;&lt;br/&gt;    &amp;lt;/div&amp;gt;&lt;br/&gt;    &amp;lt;div id="test1" class="test"&amp;gt;&lt;br/&gt;        测试1&amp;lt;/div&amp;gt;&lt;br/&gt;    &amp;lt;div id="test2" class="test"&amp;gt;&lt;br/&gt;        测试2&amp;lt;/div&amp;gt;&lt;br/&gt;    &amp;lt;div id="test3" class="test"&amp;gt;&lt;br/&gt;        测试3&amp;lt;/div&amp;gt;&lt;br/&gt;    &amp;lt;div id="test4" class="test"&amp;gt;&lt;br/&gt;        测试4&amp;lt;/div&amp;gt;&lt;br/&gt;&amp;lt;/body&amp;gt;&lt;div&gt;&lt;/div&gt;&lt;/fieldset&gt;&lt;p&gt;其中关键元素的样式如下&lt;/p&gt;&lt;fieldset style="background-color: #e0eff6; width: 900px; color: #15428b"&gt;        #holder&lt;br/&gt;        {&lt;br/&gt;            top: 0px;&lt;br/&gt;            left: 0px;&lt;br/&gt;            right: 0px;&lt;br/&gt;            bottom: 0px;&lt;br/&gt;            position: absolute;&lt;br/&gt;            z-index: 999;&lt;br/&gt;        }&lt;br/&gt;        test&lt;br/&gt;        {&lt;br/&gt;            position: absolute;&lt;br/&gt;            width: 80px;&lt;br/&gt;            height: 30px;&lt;br/&gt;            top: 0px;&lt;br/&gt;            z-index: 0;&lt;br/&gt;        }&lt;div&gt;&lt;/div&gt;&lt;/fieldset&gt;&lt;p&gt;在拖动事件中，动态改变了节点文本元素的位置&lt;/p&gt;&lt;p&gt;并且重绘了节点和箭头&lt;/p&gt;&lt;p&gt;drawArr是一个自定义方法，负责修改箭头的方向，代码如下&lt;/p&gt;&lt;fieldset style="background-color: #e0eff6; width: 900px; color: #15428b"&gt;        //随着节点位置的改变动态改变箭头&lt;br/&gt;        Raphael.fn.drawArr = function (obj) {&lt;br/&gt;            var point = getStartEnd(obj.obj1, obj.obj2);&lt;br/&gt;            var path1 = getArr(point.start.x, point.start.y, point.end.x, point.end.y, 8);&lt;br/&gt;            if (obj.arrPath) {&lt;br/&gt;                obj.arrPath.attr({ path: path1 });&lt;br/&gt;            } else {&lt;br/&gt;                obj.arrPath = this.path(path1);&lt;br/&gt;            }&lt;br/&gt;            return obj;&lt;br/&gt;        };&lt;div&gt;&lt;/div&gt;&lt;/fieldset&gt;&lt;p&gt;首先需要确定箭头的起始位置，&lt;/p&gt;&lt;p&gt;point包含两个点，&lt;/p&gt;&lt;p&gt;point.start为起点,&lt;/p&gt;&lt;p&gt;point.end为终点，&lt;/p&gt;&lt;p&gt;然后需要确定箭头的绘图路径&lt;/p&gt;&lt;p&gt;一个箭头包含三个线段，四个点&lt;/p&gt;&lt;p&gt;1:起点，2:终点，3:箭头终点1，4:箭头终点2&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201205/201205181116582159.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201205/201205181116583239.png" width="376" height="173"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;在此函数中，判断如果箭头已经被绘制过，&lt;/p&gt;&lt;p&gt;只要修改属性即可&lt;/p&gt;&lt;p&gt;如果没有被绘制过，则需要重新绘制&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;下面来看一下动态确定起点和终点的代码&lt;/p&gt;&lt;fieldset style="background-color: #e0eff6; width: 900px; color: #15428b"&gt;function getStartEnd(obj1, obj2) {&lt;br/&gt;            var bb1 = obj1.getBBox(),&lt;br/&gt;                bb2 = obj2.getBBox();&lt;br/&gt;            var p = [&lt;br/&gt;                    { x: bb1.x + bb1.width / 2, y: bb1.y - 1 },&lt;br/&gt;                    { x: bb1.x + bb1.width / 2, y: bb1.y + bb1.height + 1 },&lt;br/&gt;                    { x: bb1.x - 1, y: bb1.y + bb1.height / 2 },&lt;br/&gt;                    { x: bb1.x + bb1.width + 1, y: bb1.y + bb1.height / 2 },&lt;br/&gt;                    { x: bb2.x + bb2.width / 2, y: bb2.y - 1 },&lt;br/&gt;                    { x: bb2.x + bb2.width / 2, y: bb2.y + bb2.height + 1 },&lt;br/&gt;                    { x: bb2.x - 1, y: bb2.y + bb2.height / 2 },&lt;br/&gt;                    { x: bb2.x + bb2.width + 1, y: bb2.y + bb2.height / 2 }&lt;br/&gt;                ];&lt;br/&gt;            var d = {}, dis = [];&lt;br/&gt;            for (var i = 0; i &amp;lt; 4; i++) {&lt;br/&gt;                for (var j = 4; j &amp;lt; 8; j++) {&lt;br/&gt;                    var dx = Math.abs(p[i].x - p[j].x),&lt;br/&gt;                        dy = Math.abs(p[i].y - p[j].y);&lt;br/&gt;                    if (&lt;br/&gt;                         (i == j - 4) ||&lt;br/&gt;                         (((i != 3 &amp;amp;&amp;amp; j != 6) || p[i].x &amp;lt; p[j].x) &amp;amp;&amp;amp;&lt;br/&gt;                         ((i != 2 &amp;amp;&amp;amp; j != 7) || p[i].x &amp;gt; p[j].x) &amp;amp;&amp;amp;&lt;br/&gt;                         ((i != 0 &amp;amp;&amp;amp; j != 5) || p[i].y &amp;gt; p[j].y) &amp;amp;&amp;amp;&lt;br/&gt;                         ((i != 1 &amp;amp;&amp;amp; j != 4) || p[i].y &amp;lt; p[j].y))&lt;br/&gt;                       ) {&lt;br/&gt;                        dis.push(dx + dy);&lt;br/&gt;                        d[dis[dis.length - 1]] = [i, j];&lt;br/&gt;                    }&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;            if (dis.length == 0) {&lt;br/&gt;                var res = [0, 4];&lt;br/&gt;            } else {&lt;br/&gt;                res = d[Math.min.apply(Math, dis)];&lt;br/&gt;            }&lt;br/&gt;            var result = {};&lt;br/&gt;            result.start = {};&lt;br/&gt;            result.end = {};&lt;br/&gt;            result.start.x = p[res[0]].x;&lt;br/&gt;            result.start.y = p[res[0]].y;&lt;br/&gt;            result.end.x = p[res[1]].x;&lt;br/&gt;            result.end.y = p[res[1]].y;&lt;br/&gt;            return result;&lt;br/&gt;        }&lt;div&gt;&lt;/div&gt;&lt;/fieldset&gt;&lt;p&gt;这段代码来自Raphael官方demo&lt;/p&gt;&lt;p&gt;不是我写的&lt;/p&gt;&lt;p&gt;也一时半会说不清楚，&lt;/p&gt;&lt;p&gt;大家还是自己去研究吧&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;确定箭头路径的代码如下&lt;/p&gt;&lt;fieldset style="background-color: #e0eff6; width: 900px; color: #15428b"&gt;        //获取组成箭头的三条线段的路径&lt;br/&gt;        function getArr(x1, y1, x2, y2, size) {&lt;br/&gt;            var angle = Raphael.angle(x1, y1, x2, y2);//得到两点之间的角度&lt;br/&gt;            var a45 = Raphael.rad(angle - 45);//角度转换成弧度&lt;br/&gt;            var a45m = Raphael.rad(angle + 45);&lt;br/&gt;            var x2a = x2 + Math.cos(a45) * size;&lt;br/&gt;            var y2a = y2 + Math.sin(a45) * size;&lt;br/&gt;            var x2b = x2 + Math.cos(a45m) * size;&lt;br/&gt;            var y2b = y2 + Math.sin(a45m) * size;&lt;br/&gt;            var result = ["M", x1, y1, "L", x2, y2, "L", x2a, y2a, "M", x2, y2, "L", x2b, y2b];&lt;br/&gt;            return result;&lt;br/&gt;        }&lt;div&gt;&lt;/div&gt;&lt;/fieldset&gt;&lt;p&gt;此函数把箭头路径作为数组反馈给调用函数&lt;/p&gt;&lt;p&gt;数组中&lt;/p&gt;&lt;p&gt;M表示画笔起点移动到此点&lt;/p&gt;&lt;p&gt;L表示从某点绘制到某点，绘制直线&lt;/p&gt;&lt;p&gt;以上函数反馈结果的意思是：&lt;/p&gt;&lt;p&gt;画笔从（x1,y1）开始绘制直线到(x2,y2),然后从(x2,y2)绘制直线到(x2a,y2a)然后画笔移动到(x2,y2)然后从(x2,y2)绘制直线到(x2b,y2b)&lt;/p&gt;&lt;p&gt;在确定这几个点的过程中&lt;/p&gt;&lt;p&gt;用到了一些数学知识，具体原理也不多说了&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;喜欢的朋友请点支持！谢谢大家！&lt;/p&gt;&lt;img src="http://www.cnblogs.com/liulun/aggbug/2507472.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/liulun/archive/2012/05/18/2507472.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/liulun/archive/2012/03/30/2424775.html</id><title type="text">【翻译】Windows8支持WebSocket（相关技术）</title><summary type="text">原文地址： http://www.infoq.com/news/2012/03/websocket-windows 鉴于Windows 8客户预览版已经很好的支持WebSocket协议和WebSocket API asp.net 开发人员可以使用System.Web.Websockets类库来实现双向通信的功能 在windows 8客户预览版和Server beta版本中 IE10、所有的微软...</summary><published>2012-03-30T02:29:00Z</published><updated>2012-03-30T02:29:00Z</updated><author><name>liulun</name><uri>http://www.cnblogs.com/liulun/</uri></author><link rel="alternate" href="http://www.cnblogs.com/liulun/archive/2012/03/30/2424775.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/liulun/archive/2012/03/30/2424775.html"/><content type="html">&lt;p&gt;原文地址：&lt;/p&gt; &lt;p&gt;&lt;a title="http://www.infoq.com/news/2012/03/websocket-windows" href="http://www.infoq.com/news/2012/03/websocket-windows"&gt;http://www.infoq.com/news/2012/03/websocket-windows&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;鉴于Windows 8客户预览版已经很好的支持WebSocket协议和WebSocket API&lt;/p&gt; &lt;p&gt;asp.net 开发人员可以使用System.Web.Websockets类库来实现双向通信的功能&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;在windows 8客户预览版和Server beta版本中&lt;/p&gt; &lt;p&gt;IE10、所有的微软WebSocket客户端和服务端功能都支持&lt;/p&gt; &lt;p&gt;最新版本的 &lt;a href="http://www.rfc-editor.org/rfc/rfc6455.txt"&gt;IETF WebSocket 协议&lt;/a&gt;&lt;/p&gt; &lt;p&gt;另外，IE10还实现了W3C的候选版 &lt;a href="http://www.w3.org/TR/websockets/"&gt;WebSocketAPI&lt;/a&gt;&lt;/p&gt; &lt;p&gt;微软IE团队的官方博客详细解释了&lt;a href="http://blogs.msdn.com/b/ie/archive/2012/03/19/websockets-in-windows-consumer-preview.aspx"&gt;这些内容&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;与此同时，&lt;/p&gt; &lt;p&gt;ASP.NET开发人员可以使用&lt;a href="http://msdn.microsoft.com/en-us/library/ms171868(v=vs.110).aspx"&gt;.Net Framework4.5&lt;/a&gt;引入的&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.asp.net/vnext/overview/whitepapers/whats-new#_Toc318097383"&gt;System.Web.WebSocket名称空间&lt;/a&gt;来使用此项技术&lt;/p&gt; &lt;p&gt;这个名称空间不同于System.Net.Websockets名称空间&lt;/p&gt; &lt;p&gt;前者把这些技术集成到asp.net框架中&lt;/p&gt; &lt;p&gt;后者只是提供了.Net框架下标准WebSocket的实现&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.infoq.com/presentations/WebSockets-The-Web-Communication-Revolution"&gt;WebSocket技术&lt;/a&gt;提供了基于TCP Socket的双向通信信道技术&lt;/p&gt; &lt;p&gt;这与&lt;a href="http://en.wikipedia.org/wiki/Comet_(programming)"&gt;Comet Channels&lt;/a&gt;技术很接近&lt;/p&gt; &lt;p&gt;Comet Channels技术允许web服务器&lt;/p&gt; &lt;p&gt;不接受请求就直接发送数据到web客户端&lt;/p&gt; &lt;p&gt;尽管这项技术很早就已经出现了&lt;/p&gt; &lt;p&gt;（&lt;a href="http://blog.chromium.org/2009/12/web-sockets-now-available-in-google.html"&gt;谷歌chorme浏览器早在2009年就宣布支持Comet Channels&lt;/a&gt;）&lt;/p&gt; &lt;p&gt;但是直到去年12月份，&lt;/p&gt; &lt;p&gt;Internet Engineering Task Force才接受它&lt;/p&gt;&lt;img src="http://www.cnblogs.com/liulun/aggbug/2424775.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/liulun/archive/2012/03/30/2424775.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/liulun/archive/2012/03/28/2420970.html</id><title type="text">【翻译】Prism4：初始化Prism应用程序（上）</title><summary type="text">什么是Bootstrapper（引导程序） bootstrapper负责初始化使用Prism类库搭建的应用程序 使用bootstrapper，你可以更方便的控制Prism类库组件与你的应用程序之间的关系 Prism类库包含一个默认的抽象基类Bootstrapper 这个类型可以与任何容器一起使用 这个类型中的大多数方法都是虚方法 你可以在你的bootsrapper实现中重写这些方法 引导程序执...</summary><published>2012-03-28T03:43:00Z</published><updated>2012-03-28T03:43:00Z</updated><author><name>liulun</name><uri>http://www.cnblogs.com/liulun/</uri></author><link rel="alternate" href="http://www.cnblogs.com/liulun/archive/2012/03/28/2420970.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/liulun/archive/2012/03/28/2420970.html"/><content type="html">&lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;什么是Bootstrapper（引导程序）&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;bootstrapper负责初始化使用Prism类库搭建的应用程序&lt;/p&gt; &lt;p&gt;使用bootstrapper，你可以更方便的控制Prism类库组件与你的应用程序之间的关系&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Prism类库包含一个默认的抽象基类Bootstrapper&lt;/p&gt; &lt;p&gt;这个类型可以与任何容器一起使用&lt;/p&gt; &lt;p&gt;这个类型中的大多数方法都是虚方法&lt;/p&gt; &lt;p&gt;你可以在你的bootsrapper实现中重写这些方法&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;引导程序执行的基本步骤如下：&lt;/p&gt; &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201203/201203281142404.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201203/201203281142432705.png" width="478" height="324"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Prism类库提供了一些派生自Bootstrapper类的基类&lt;/p&gt; &lt;p&gt;使用这些基类可以完成绝大多数应用程序&lt;/p&gt; &lt;p&gt;继承实现bootsrapper，&lt;/p&gt; &lt;p&gt;你需要做的工作只是创建和初始化框架界面&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;依赖注入&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;使用Prism类库搭建的应用程序需要使用依赖注入容器&lt;/p&gt; &lt;p&gt;Prism支持Unity和MEF依赖注入容器&lt;/p&gt; &lt;p&gt;并且允许使用其他的依赖注入容器&lt;/p&gt; &lt;p&gt;引导程序的部分工作就是装配这个容器&lt;/p&gt; &lt;p&gt;并为容器注册类型&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Prism类库包含UnityBootstrapper和MefBootstrapper类&lt;/p&gt; &lt;p&gt;这两个类实现了使用Unity或MEF所必须的功能&lt;/p&gt; &lt;p&gt;除了在前面的插图中展示的步骤&lt;/p&gt; &lt;p&gt;这两个类型还添加了针对各自容器的特殊步骤&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;创建框架&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#000000"&gt;一般创建WPF应用程序，&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#000000"&gt;APP.XAML中会指定一个启动画面的URI&lt;/font&gt;&lt;/p&gt; &lt;p&gt;在Silverlight应用程序中&lt;/p&gt; &lt;p&gt;APP.XAML的后端代码中指定了系统的RootVisual属性&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;使用Prism类库创建应用程序&lt;/p&gt; &lt;p&gt;bootstrapper负责创建框架画面&lt;/p&gt; &lt;p&gt;这主要是因为框架画面依赖于服务&lt;/p&gt; &lt;p&gt;这些服务类似与区域主管&lt;/p&gt; &lt;p&gt;这些服务在框架画面显示之前被注册&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;关键决定&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;当你决定使用Prism类库&lt;/p&gt; &lt;p&gt;还需要做出一些额外的决定：&lt;/p&gt; &lt;p&gt;必须决定是使用MEF、Unity还是其他的依赖注入容器&lt;/p&gt; &lt;p&gt;这决定你应该选择哪个bootstrapper类型&lt;/p&gt; &lt;p&gt;还是需要为你自己的依赖注入容器创建一个新的bootstrapper类型&lt;/p&gt; &lt;p&gt;你应该考虑你系统中的特殊服务单元，&lt;/p&gt; &lt;p&gt;这些需要注册到依赖注入容器内&lt;/p&gt; &lt;p&gt;判断是否系统内部集成的日志服务足够你使用了，&lt;/p&gt; &lt;p&gt;如果不够你要自己创建你自己的日志服务&lt;/p&gt; &lt;p&gt;决定系统如何发现模块&lt;/p&gt; &lt;p&gt;使用目录查找、配置文件、或者xaml来加载模块&lt;/p&gt; &lt;p&gt;（模块必须由明确的特性代码标记）&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;关键场景&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;指定有序的启动环节&lt;/p&gt; &lt;p&gt;对你创建Prism应用程序来说非常有用&lt;/p&gt; &lt;p&gt;这一小节主要描述怎样创建一个bootstrapper（引导程序）、&lt;/p&gt; &lt;p&gt;并定制这个引导程序以启动自己的框架画面、&lt;/p&gt; &lt;p&gt;配置依赖注入容器、&lt;/p&gt; &lt;p&gt;注册系统级别的服务、&lt;/p&gt; &lt;p&gt;怎样加载和初始化模块&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;为你的应用程序创建Bootstrapper&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#000000"&gt;无论你是选择使用Unity还是MEF作为你的依赖注入容器&lt;/font&gt;&lt;/p&gt; &lt;p&gt;为你的应用程序创建一个简单的bootstrapper&lt;/p&gt; &lt;p&gt;都是非常容易的&lt;/p&gt; &lt;p&gt;你可以创建一个派生自MefBootstrapper或者UnityBootstrapper的类&lt;/p&gt; &lt;p&gt;然后重写CreateShell方法&lt;/p&gt; &lt;p&gt;有时候你还需要为了特殊的业务需求而重写InitializeShell方法&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;实现CreateShell方法&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;CreateShell方法允许开发人员指定Prism应用程序的top-level（顶层）窗口&lt;/p&gt; &lt;p&gt;Shell通常是指主窗口或注页面&lt;/p&gt; &lt;p&gt;在这个方法的具体实现中返回一个Shell的实例&lt;/p&gt; &lt;p&gt;在Prism应用程序中&lt;/p&gt; &lt;p&gt;你可以创建一个Shell的实例&lt;/p&gt; &lt;p&gt;也可以从依赖注入容器中取出shell的对象&lt;/p&gt; &lt;p&gt;选择哪种办法，就看你的需求了。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;使用ServiceLocator从依赖注入容器中取出&lt;/p&gt; &lt;p&gt;shell对象的示例代码如下：&lt;/p&gt; &lt;fieldset style="background-color: #e0eff6; width: 900px; color: #15428b"&gt;protected override DependencyObject CreateShell()&lt;br/&gt;{&lt;br/&gt;    return ServiceLocator.Current.GetInstance&amp;lt;Shell&amp;gt;();&lt;br/&gt;}&lt;/fieldset&gt; &lt;p&gt;你会经常使用ServiceLocator（而不是特殊的依赖注入容器）来解析一些类型的实例&lt;/p&gt;&lt;p&gt;ServiceLocator实现了调用依赖注入容器的逻辑&lt;/p&gt;&lt;p&gt;这样主要是为了应对依赖注入容器代码不容易控制的特性&lt;/p&gt;&lt;p&gt;你也可以通过直接引用类库来使用依赖注入容器&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;实现InitializeShell方法&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;当你创建了一个框架画面(shell)&lt;/p&gt;&lt;p&gt;你需要执行初始化的几个步骤来确定你的框架画面可以被正常显示&lt;/p&gt;&lt;p&gt;开发WPF和开发Silverlight应用程序&lt;/p&gt;&lt;p&gt;InitializeShell方法的实现方式也会不同&lt;/p&gt;&lt;p&gt;对于Silverlight应用程序来说&lt;/p&gt;&lt;p&gt;你需要把框架画面设置成系统的visual root&lt;/p&gt;&lt;p&gt;代码如下：&lt;/p&gt;&lt;fieldset style="background-color: #e0eff6; width: 900px; color: #15428b"&gt;protected override void InitializeShell()&lt;br/&gt;{&lt;br/&gt;    Application.Current.RootVisual = Shell;&lt;br/&gt;}&lt;/fieldset&gt;&lt;p&gt;对于WPF应用程序&lt;/p&gt;&lt;p&gt;你必须先实例化shell类型&lt;/p&gt;&lt;p&gt;然后把这个实例设置成系统的主窗口&lt;/p&gt;&lt;p&gt;代码如下：&lt;/p&gt;&lt;fieldset style="background-color: #e0eff6; width: 900px; color: #15428b"&gt;protected override void InitializeShell()&lt;br/&gt;{&lt;br/&gt;    Application.Current.MainWindow = Shell;&lt;br/&gt;    Application.Current.MainWindow.Show();&lt;br/&gt;}&lt;/fieldset&gt;&lt;p&gt;基类的InitializeShell方法什么也没有做，是个空方法&lt;/p&gt;&lt;p&gt;不调用基类的InitializeShell方法也没有关系。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/liulun/aggbug/2420970.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/liulun/archive/2012/03/28/2420970.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/liulun/archive/2012/03/26/2417419.html</id><title type="text">【翻译】WPF应用程序模块化开发快速入门（使用Prism+MEF）【下】</title><summary type="text">索引【翻译】WPF应用程序模块化开发快速入门（使用Prism框架）【上】【翻译】WPF应用程序模块化开发快速入门（使用Prism+MEF）【中】系统启动系统使用Bootstrapper类型来启动程序，并初始化主窗口 /// &lt;summary&gt; /// Interaction logic for App.xaml /// &lt;/summary&gt; public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { ...</summary><published>2012-03-26T01:51:00Z</published><updated>2012-03-26T01:51:00Z</updated><author><name>liulun</name><uri>http://www.cnblogs.com/liulun/</uri></author><link rel="alternate" href="http://www.cnblogs.com/liulun/archive/2012/03/26/2417419.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/liulun/archive/2012/03/26/2417419.html"/><content type="html">&lt;p&gt;&lt;strong&gt;索引&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/liulun/archive/2012/03/16/2399654.html"&gt;【翻译】WPF应用程序模块化开发快速入门（使用Prism框架）【上】&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/liulun/archive/2012/03/19/2405940.html"&gt;【翻译】WPF应用程序模块化开发快速入门（使用Prism+MEF）【中】&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;系统启动&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;系统使用Bootstrapper类型来启动程序，并初始化主窗口&lt;/p&gt;    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/// Interaction logic for App.xaml&lt;/span&gt;&lt;br/&gt;    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; App : Application&lt;br/&gt;    {&lt;br/&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnStartup(StartupEventArgs e)&lt;br/&gt;        {&lt;br/&gt;            &lt;span class="kwrd"&gt;base&lt;/span&gt;.OnStartup(e);&lt;br/&gt;&lt;br/&gt;            &lt;span class="rem"&gt;// The boostrapper will create the Shell instance, so the App.xaml does not have a StartupUri.&lt;/span&gt;&lt;br/&gt;            QuickStartBootstrapper bootstrapper = &lt;span class="kwrd"&gt;new&lt;/span&gt; QuickStartBootstrapper();&lt;br/&gt;            bootstrapper.Run();&lt;br/&gt;        }&lt;br/&gt;    }&amp;nbsp;&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;QuickStartBootstrapper类型继承自MefBootstrapper类型&lt;/p&gt;&lt;p&gt;为了创建和显示主窗口，此类型重写了CreateShell和InitializeShell方法&lt;/p&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; DependencyObject CreateShell()&lt;br/&gt;        {&lt;br/&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.Container.GetExportedValue&amp;lt;Shell&amp;gt;();&lt;br/&gt;        }        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; InitializeShell()&lt;br/&gt;        {&lt;br/&gt;            &lt;span class="kwrd"&gt;base&lt;/span&gt;.InitializeShell();&lt;br/&gt;&lt;br/&gt;            Application.Current.MainWindow = (Shell) &lt;span class="kwrd"&gt;this&lt;/span&gt;.Shell;&lt;br/&gt;            Application.Current.MainWindow.Show();&lt;br/&gt;        }&amp;nbsp;&amp;nbsp;&lt;strong&gt;创建模块&lt;/strong&gt;在此快速入门示例中创建了六个模块这些模块都实现了IModule接口添加了相关的特性选择了依赖属性    [ModuleExport(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(ModuleA), DependsOnModuleNames = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] { &lt;span class="str"&gt;"ModuleD"&lt;/span&gt; })]&lt;br/&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ModuleA : IModule&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;当使用MEF框架的时候ModuleExport特性允许MEF发现适当的、继承自IModule接口的类型。此外：它还支持详细说明额外模块的元数据&lt;strong&gt;注册模块&lt;/strong&gt;在快速入门示例中系统直接引用了一些模块通过监控目录发现了一些模块还有一些模块是通过配置文件加载的QuickStartBootstrapper类型还重写了CreateModuleCatalog和ConfigureModuleCatalog方法这样就可以通过配置文件来注册模块使用MEF时AggregateCatalog支持发现模块和类型基于此，QuickStartBootstrapper重写ConfigureAggregateCatalog模版方法并使用MEF注册程序集仍然使用ModuleCatalog加载配置文件来注册模块        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; IModuleCatalog CreateModuleCatalog()&lt;br/&gt;        {&lt;br/&gt;            &lt;span class="rem"&gt;// When using MEF, the existing Prism ModuleCatalog is still the place to configure modules via configuration files.&lt;/span&gt;&lt;br/&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; ConfigurationModuleCatalog();&lt;br/&gt;        }&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;        &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ConfigureAggregateCatalog()&lt;br/&gt;        {&lt;br/&gt;            &lt;span class="kwrd"&gt;base&lt;/span&gt;.ConfigureAggregateCatalog();&lt;br/&gt;&lt;br/&gt;            &lt;span class="rem"&gt;// Add this assembly to export ModuleTracker&lt;/span&gt;&lt;br/&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.AggregateCatalog.Catalogs.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; AssemblyCatalog(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(QuickStartBootstrapper).Assembly));&lt;br/&gt;&lt;br/&gt;            &lt;span class="rem"&gt;// Module A is referenced in in the project and directly in code.&lt;/span&gt;&lt;br/&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.AggregateCatalog.Catalogs.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; AssemblyCatalog(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(ModuleA).Assembly));&lt;br/&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.AggregateCatalog.Catalogs.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; AssemblyCatalog(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(ModuleC).Assembly));&lt;br/&gt;&lt;br/&gt;            &lt;span class="rem"&gt;// Module B and Module D are copied to a directory as part of a post-build step.&lt;/span&gt;&lt;br/&gt;            &lt;span class="rem"&gt;// These modules are not referenced in the project and are discovered by inspecting a directory.&lt;/span&gt;&lt;br/&gt;            &lt;span class="rem"&gt;// Both projects have a post-build step to copy themselves into that directory.&lt;/span&gt;&lt;br/&gt;            DirectoryCatalog catalog = &lt;span class="kwrd"&gt;new&lt;/span&gt; DirectoryCatalog(&lt;span class="str"&gt;"DirectoryModules"&lt;/span&gt;);&lt;br/&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.AggregateCatalog.Catalogs.Add(catalog);&lt;br/&gt;        }&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;p&gt;&lt;strong&gt;加载模块&lt;/strong&gt;&lt;/p&gt;&lt;strong&gt;&lt;/strong&gt; 在此快速入门中即有在系统启动时加载模块的业务也有按需加载模块的业务还有显示进度、控制模块间的依赖性等业务注意：此快速入门示例还有一些额外的类以帮助追踪模块初始化的状态信息这些类主要是起了示范的目的Shell的用户界面里包含了六个ModuleControlShell的DataContext是ModuleTrackerModuleTracker类型为每个模块保存一个ModuleTrackingStateModuleTrackingState绑定到与之对应的ModuleControlModuleControl使用一个默认的样式来展现模块的加载和初始化状态当点击ModuleControl自定义控件的时候将触发如下事件：        &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="rem"&gt;/// Handles the RequestModuleLoad event of the ModuleC control.&lt;/span&gt;&lt;br/&gt;        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="rem"&gt;/// &amp;lt;param name="sender"&amp;gt;The source of the event.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="rem"&gt;/// &amp;lt;param name="e"&amp;gt;The &amp;lt;see cref="System.EventArgs"/&amp;gt; instance containing the event data.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ModuleC_RequestModuleLoad(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br/&gt;        {&lt;br/&gt;            &lt;span class="rem"&gt;// The ModuleManager uses the Async Events Pattern.&lt;/span&gt;&lt;br/&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.moduleManager.LoadModule(WellKnownModuleNames.ModuleC);&lt;br/&gt;        }&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&amp;nbsp;此事件被触发的时候会同时触发moduleManager的ModuleDownloadProgressChanged事件此事件是在shell页面的OnImportsSatisfied方法中被注册的            &lt;span class="kwrd"&gt;this&lt;/span&gt;.moduleManager.LoadModuleCompleted += &lt;span class="kwrd"&gt;this&lt;/span&gt;.ModuleManager_LoadModuleCompleted;&lt;br/&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.moduleManager.ModuleDownloadProgressChanged += &lt;span class="kwrd"&gt;this&lt;/span&gt;.ModuleManager_ModuleDownloadProgressChanged;&amp;nbsp;&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;        &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="rem"&gt;/// Handles the LoadModuleProgressChanged event of the ModuleManager control.&lt;/span&gt;&lt;br/&gt;        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="rem"&gt;/// &amp;lt;param name="sender"&amp;gt;The source of the event.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="rem"&gt;/// &amp;lt;param name="e"&amp;gt;The &amp;lt;see cref="Microsoft.Practices.Composite.Modularity.ModuleDownloadProgressChangedEventArgs"/&amp;gt; instance containing the event data.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ModuleManager_ModuleDownloadProgressChanged(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, ModuleDownloadProgressChangedEventArgs e)&lt;br/&gt;        {&lt;br/&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.moduleTracker.RecordModuleDownloading(e.ModuleInfo.ModuleName, e.BytesReceived, e.TotalBytesToReceive);&lt;br/&gt;        }&lt;p&gt;当模块加载完成后&lt;/p&gt;&lt;p&gt;shell页面也会被通知到&lt;/p&gt;        &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="rem"&gt;/// Handles the LoadModuleCompleted event of the ModuleManager control.&lt;/span&gt;&lt;br/&gt;        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="rem"&gt;/// &amp;lt;param name="sender"&amp;gt;The source of the event.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="rem"&gt;/// &amp;lt;param name="e"&amp;gt;The &amp;lt;see cref="Microsoft.Practices.Composite.Modularity.LoadModuleCompletedEventArgs"/&amp;gt; instance containing the event data.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ModuleManager_LoadModuleCompleted(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, LoadModuleCompletedEventArgs e)&lt;br/&gt;        {&lt;br/&gt;            &lt;span class="kwrd"&gt;this&lt;/span&gt;.moduleTracker.RecordModuleLoaded(e.ModuleInfo.ModuleName);&lt;br/&gt;        }&lt;style&gt;&lt;!--.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }--&gt;&lt;/style&gt;&lt;strong&gt; 关键类&lt;/strong&gt;（略）这个系列含金量不高啊&lt;img src="http://www.cnblogs.com/liulun/aggbug/2417419.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/liulun/archive/2012/03/26/2417419.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/liulun/archive/2012/03/19/2405940.html</id><title type="text">【翻译】WPF应用程序模块化开发快速入门（使用Prism+MEF）【中】</title><summary type="text">索引【翻译】WPF应用程序模块化开发快速入门（使用Prism框架）【上】编译并运行快速入门需要在VisualStudio 2010上运行此快速入门示例代码下载：ModularityWithMef.zip先重新生成解决方案再按F5运行此示例说明：在此快速入门示例解决方案的ModularityWithMef.Desktop程序集中加入了生成成功时的“后期生成事件命令行”IF NOT EXIST "$(TargetDir)\DirectoryModules"mkdir "$(TargetDir)\DirectoryModules"此命令含义为：如果在此程序集的</summary><published>2012-03-19T05:14:00Z</published><updated>2012-03-19T05:14:00Z</updated><author><name>liulun</name><uri>http://www.cnblogs.com/liulun/</uri></author><link rel="alternate" href="http://www.cnblogs.com/liulun/archive/2012/03/19/2405940.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/liulun/archive/2012/03/19/2405940.html"/><content type="html">&lt;p&gt;&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;索引&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/liulun/archive/2012/03/16/2399654.html"&gt;【翻译】WPF应用程序模块化开发快速入门（使用Prism框架）【上】&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;编译并运行快速入门&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;需要在VisualStudio 2010上运行此快速入门示例&lt;/p&gt;&lt;p&gt;代码下载：&lt;a title="ModularityWithMef.zip" href="http://files.cnblogs.com/liulun/ModularityWithMef.zip"&gt;ModularityWithMef.zip&lt;/a&gt;&lt;/p&gt;&lt;p&gt;先重新生成解决方案&lt;/p&gt;&lt;p&gt;再按F5运行此示例&lt;/p&gt;&lt;p&gt;说明：&lt;/p&gt;&lt;p&gt;在此快速入门示例解决方案的&lt;/p&gt;&lt;p&gt;ModularityWithMef.Desktop程序集中&lt;/p&gt;&lt;p&gt;加入了生成成功时的&amp;ldquo;后期生成事件命令行&amp;rdquo;&lt;/p&gt;&lt;p&gt;IF NOT EXIST "$(TargetDir)\DirectoryModules"&lt;/p&gt;&lt;p&gt;mkdir "$(TargetDir)\DirectoryModules"&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;此命令含义为：&lt;/p&gt;&lt;p&gt;如果在此程序集的bin目录中没有DirectoryModules目录&lt;/p&gt;&lt;p&gt;则创建此目录&lt;/p&gt;&lt;p&gt;预先生成事件/后期生成事件命令行的宏请看MSDN的注释：&lt;/p&gt;&lt;p&gt;&lt;a title="http://msdn.microsoft.com/zh-cn/library/aa833259(v=vs.80).aspx" href="http://msdn.microsoft.com/zh-cn/library/aa833259(v=vs.80).aspx"&gt;http://msdn.microsoft.com/zh-cn/library/aa833259(v=vs.80).aspx&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;可以在程序集-&amp;gt;属性-&amp;gt;生成事件中查看修改这些命令行&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201203/201203191314008252.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201203/201203191314008775.png" alt="image" width="370" height="251" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;ModuleB程序集的成功生成时的&amp;ldquo;后期生成事件命令行&amp;rdquo;&lt;/p&gt;&lt;p&gt;xcopy "$(TargetDir)ModularityWithMef.Desktop.ModuleB.dll"&lt;/p&gt;&lt;p&gt;"$(SolutionDir)ModularityWithMef.Desktop\bin\$(ConfigurationName)\DirectoryModules\" /Y&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;含义为&lt;/p&gt;&lt;p&gt;把自身生成的dll复制到DirectoryModules目录下&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;ModuleD的程序集也有类似的命令行&lt;/p&gt;&lt;p&gt;另外&lt;/p&gt;&lt;p&gt;ModuleE和ModuleF生成的DLL会被拷贝到&lt;/p&gt;&lt;p&gt;ModularityWithMef.Desktop程序集的debug目录下&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;演练&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;运行程序&lt;/p&gt;&lt;p&gt;1.&lt;/p&gt;&lt;p&gt;主窗口包含六个模块&lt;/p&gt;&lt;p&gt;每个模块都展示了各自的初始化状态。&lt;/p&gt;&lt;p&gt;应用程序加载的时候&lt;/p&gt;&lt;p&gt;程序就发现并初始化了模块A和模块D&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201203/201203191314039284.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201203/201203191314052707.png" alt="image" width="318" height="302" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;程序启动的时候，通过监视目录，&lt;/p&gt;&lt;p&gt;发现了ModuleD，就把它初始化了。&lt;/p&gt;&lt;p&gt;当模块A可用的时候才可被加载&lt;/p&gt;&lt;p&gt;模块A依赖于模块D&lt;/p&gt;&lt;p&gt;当模块D加载之后，模块A才被初始化&lt;/p&gt;&lt;p&gt;窗口下部的跟踪区域显示了模块初始化的信息&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;注意：&lt;/p&gt;&lt;p&gt;如果没有依赖关系的话，模块的加载是无顺序的。&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;2.&lt;/p&gt;&lt;p&gt;鼠标移动到模块A控件上，显示了一个描述性提示，如下图：&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201203/201203191314068496.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201203/20120319131406939.png" alt="image" width="303" height="207" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;3.&lt;/p&gt;&lt;p&gt;提示信息为：&lt;/p&gt;&lt;p&gt;当前控件的状态，是否被发现，&lt;/p&gt;&lt;p&gt;是否被初始化，下载时间和依赖性等信息&lt;/p&gt;&lt;p&gt;4.&lt;/p&gt;&lt;p&gt;点击模块B和模块C&lt;/p&gt;&lt;p&gt;两个模块的初始化信息都会随之改变&lt;/p&gt;&lt;p&gt;点击这两个模块会触发这两个模块的加载事件&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201203/20120319131411618.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201203/201203191314139373.png" alt="image" width="329" height="303" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;系统通过监视文件夹发现模块B&lt;/p&gt;&lt;p&gt;模块C是被直接引用到系统中的&lt;/p&gt;&lt;p&gt;这两个模块都是在需要的时候才被加载的&lt;/p&gt;&lt;p&gt;5.&lt;/p&gt;&lt;p&gt;当点击模块F的时候，&lt;/p&gt;&lt;p&gt;模块E和模块F被加载。如下图&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201203/201203191314154125.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201203/201203191314177482.png" alt="image" width="360" height="334" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;虽然模块F先被点击&lt;/p&gt;&lt;p&gt;但是由于依赖关系的原因&lt;/p&gt;&lt;p&gt;系统先初始化模块E，再初始化模块F&lt;/p&gt;&lt;img src="http://www.cnblogs.com/liulun/aggbug/2405940.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/liulun/archive/2012/03/19/2405940.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/liulun/archive/2012/03/16/2399654.html</id><title type="text">【翻译】WPF应用程序模块化开发快速入门（使用Prism框架）【上】</title><summary type="text">这篇快速入门文章包括如何使用Prism进行编码、探索和创建模块的示例创建模块：模块是实现了IModule接口的类，可以通过声明特性来给模块命名、控制其初始化、定义依赖等注册模块：模块可以通过以下方式注册：直接使用代码：可以直接使用代码把模块注册到模块目录这样你就可以咱找业务逻辑来决定哪些模块需要注册到系统中来在代码中注册的模块需要引用到系统中来，不能在运行时动态加载使用配置文件：Prism支持通过加载一个配置文件来注册模块这与在Silverlight中使用XAML方法注册模块的场景非常类似在配置文件中声明模块可以让系统决定什么时候加载和初始化模块通过监视目录可以指定一个目录，如果有程序集被添加</summary><published>2012-03-16T00:15:00Z</published><updated>2012-03-16T00:15:00Z</updated><author><name>liulun</name><uri>http://www.cnblogs.com/liulun/</uri></author><link rel="alternate" href="http://www.cnblogs.com/liulun/archive/2012/03/16/2399654.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/liulun/archive/2012/03/16/2399654.html"/><content type="html">&lt;p&gt;这篇快速入门文章包括如何使用Prism进行编码、探索和创建模块的示例&lt;/p&gt;&lt;p&gt;&lt;strong&gt;创建模块：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;模块是实现了IModule接口的类，&lt;/p&gt;&lt;p&gt;可以通过声明特性来给模块命名、控制其初始化、定义依赖等&lt;/p&gt;&lt;p&gt;&lt;strong&gt;注册模块：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;模块可以通过以下方式注册：&lt;/p&gt;&lt;p&gt;直接使用代码：&lt;/p&gt;&lt;p&gt;可以直接使用代码把模块注册到模块目录&lt;/p&gt;&lt;p&gt;这样你就可以咱找业务逻辑来决定哪些模块需要注册到系统中来&lt;/p&gt;&lt;p&gt;在代码中注册的模块需要引用到系统中来，不能在运行时动态加载&lt;/p&gt;&lt;p&gt;使用配置文件：&lt;/p&gt;&lt;p&gt;Prism支持通过加载一个配置文件来注册模块&lt;/p&gt;&lt;p&gt;这与在Silverlight中使用XAML方法注册模块的场景非常类似&lt;/p&gt;&lt;p&gt;在配置文件中声明模块可以让系统决定什么时候加载和初始化模块&lt;/p&gt;&lt;p&gt;通过监视目录&lt;/p&gt;&lt;p&gt;可以指定一个目录，&lt;/p&gt;&lt;p&gt;如果有程序集被添加到此目录中，&lt;/p&gt;&lt;p&gt;系统将自动发现程序集内的模块。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;注册模块依赖：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;模块可以依赖于其他模块，&lt;/p&gt;&lt;p&gt;Prism支持管理依赖。&lt;/p&gt;&lt;p&gt;包括控制循环引用和重复模块检测等功能。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;初始化化模块：&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;prism支持两种初始化模块的方式：&lt;/p&gt;&lt;p&gt;在可用的时候初始化：&lt;/p&gt;&lt;p&gt;模块可以在其可用的时候即马上被初始化，&lt;/p&gt;&lt;p&gt;模块在应用程序启动的时候被下载，&lt;/p&gt;&lt;p&gt;当模块在后台线程中下载完毕后马上就被初始化了。&lt;/p&gt;&lt;p&gt;在需要的时候初始化：&lt;/p&gt;&lt;p&gt;模块可以在系统代码调用它的时候再进行初始化，&lt;/p&gt;&lt;p&gt;当系统代码调用模块的时候，后台线程开始下载模块&lt;/p&gt;&lt;p&gt;当模块下载成功后马上初始化&lt;/p&gt;&lt;p&gt;&lt;strong&gt;在后台下载模块&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;尽管对于silverlight应用程序来说在后台下载模块是非常有用&lt;/p&gt;&lt;p&gt;桌面应用程序现在也可以利用这个改进来发现和加载程序集&lt;/p&gt;&lt;p&gt;显示进度：&lt;/p&gt;&lt;p&gt;应用程序可以订阅一个&amp;ldquo;进度改变&amp;rdquo;事件&lt;/p&gt;&lt;p&gt;以展示下载的byte数量和下载进度百分比，&lt;/p&gt;&lt;p&gt;下载完成行为：&lt;/p&gt;&lt;p&gt;程序可以订阅一个加载&amp;ldquo;模块完成&amp;rdquo;事件，&lt;/p&gt;&lt;p&gt;以处理模块加载和初始化完成后的额外事件&lt;/p&gt;&lt;p&gt;&lt;strong&gt;使用不同的依赖注入容器&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;一般在&amp;ldquo;快速入门&amp;rdquo;的示例中都是使用Unity依赖注入容器&lt;/p&gt;&lt;p&gt;虽然核心类库的代码仍然&amp;ldquo;容器-未知&amp;rdquo;（container-agnostic）&lt;/p&gt;&lt;p&gt;但却使用了.Net4的MEF依赖注入容器插件。&lt;/p&gt;&lt;p&gt;这里有两个使用不同依赖注入容器的快速入门示例&lt;/p&gt;&lt;p&gt;MEF模块化：&lt;/p&gt;&lt;p&gt;此模块化快速入门示例使用MEF倚赖注入容器&lt;/p&gt;&lt;p&gt;Prism推荐使用MEF的声明式特性&lt;/p&gt;&lt;p&gt;使ModuleCatalog和MEF的ComposablePartsCatalog成为一体&lt;/p&gt;&lt;p&gt;Unity模块化：&lt;/p&gt;&lt;p&gt;此模块化快速入门示例使用Unity倚赖注入容器&lt;/p&gt;&lt;p&gt;&lt;strong&gt;场景&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这一小节描述两个快速入门示例的相同场景，&lt;/p&gt;&lt;p&gt;每个快速入门示例都由六个模块组成&lt;/p&gt;&lt;p&gt;ModuleA、ModuleB、ModuleC、ModuleD、ModuleE、ModuleF&lt;/p&gt;&lt;p&gt;这些模块示例展示了模块是怎么被发现、下载和初始化的&lt;/p&gt;&lt;table style="width: 511px;" border="0" cellspacing="0" cellpadding="2"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top" width="80"&gt;模块&lt;/td&gt;&lt;td valign="top" width="100"&gt;注册方式&lt;/td&gt;&lt;td valign="top" width="114"&gt;初始化方式&lt;/td&gt;&lt;td valign="top" width="154"&gt;下载方式&lt;/td&gt;&lt;td valign="top" width="61"&gt;依赖&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="80"&gt;A&lt;/td&gt;&lt;td valign="top" width="100"&gt;代码&lt;/td&gt;&lt;td valign="top" width="114"&gt;直接&lt;/td&gt;&lt;td valign="top" width="154"&gt;随程序集&lt;/td&gt;&lt;td valign="top" width="61"&gt;D&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="80"&gt;B&lt;/td&gt;&lt;td valign="top" width="100"&gt;目录&lt;/td&gt;&lt;td valign="top" width="114"&gt;按需&lt;/td&gt;&lt;td valign="top" width="154"&gt;后台&lt;/td&gt;&lt;td valign="top" width="61"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="80"&gt;C&lt;/td&gt;&lt;td valign="top" width="100"&gt;代码&lt;/td&gt;&lt;td valign="top" width="114"&gt;按需&lt;/td&gt;&lt;td valign="top" width="154"&gt;随程序集&lt;/td&gt;&lt;td valign="top" width="61"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="80"&gt;D&lt;/td&gt;&lt;td valign="top" width="100"&gt;目录&lt;/td&gt;&lt;td valign="top" width="114"&gt;直接&lt;/td&gt;&lt;td valign="top" width="154"&gt;后台&lt;/td&gt;&lt;td valign="top" width="61"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="80"&gt;E&lt;/td&gt;&lt;td valign="top" width="100"&gt;配置&lt;/td&gt;&lt;td valign="top" width="114"&gt;按需&lt;/td&gt;&lt;td valign="top" width="154"&gt;后台&lt;/td&gt;&lt;td valign="top" width="61"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top" width="80"&gt;F&lt;/td&gt;&lt;td valign="top" width="100"&gt;配置&lt;/td&gt;&lt;td valign="top" width="114"&gt;按需&lt;/td&gt;&lt;td valign="top" width="154"&gt;后台&lt;/td&gt;&lt;td valign="top" width="61"&gt;E&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;每个示例中所有的模块都是一个控件&lt;/p&gt;&lt;p&gt;这些控件展示了以下信息：&lt;/p&gt;&lt;p&gt;是否已经被初始化、下载进度、按需加载的控件可以在点击事件中初始化&lt;/p&gt;&lt;p&gt;这些控件还提供了一个tooltip&lt;/p&gt;&lt;p&gt;以显示它现在的初始化状态和被发现的信息&lt;/p&gt;&lt;p&gt;在快速入门示例的最下面&lt;/p&gt;&lt;p&gt;有一个TextBox控件&lt;/p&gt;&lt;p&gt;在这里展示从程序创建开始到模块加载过程中的日志记录&lt;/p&gt;&lt;p&gt;下图为使用模块化MEF快速入门示例的主页&lt;/p&gt;&lt;p&gt;模块化快速入门示例的用户界面（桌面版本）&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201203/20120316081503835.png"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201203/201203160815048718.png" alt="image" width="385" height="362" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;----------------------------------------------------------------&lt;/p&gt;&lt;p&gt;原文是个PDF中的一部分&lt;/p&gt;&lt;p&gt;在这里下载的&lt;/p&gt;&lt;p&gt;&lt;a title="http://mef.codeplex.com/" href="http://mef.codeplex.com/"&gt;http://mef.codeplex.com/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;您的推荐是我把这个系列写完的动力~&lt;/p&gt;&lt;img src="http://www.cnblogs.com/liulun/aggbug/2399654.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/liulun/archive/2012/03/16/2399654.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/liulun/archive/2012/02/26/2368635.html</id><title type="text">【翻译】VisualStudio11中的CSS编辑器改进（asp.net 4.5系列）-ScottGu</title><summary type="text">这是我所发的关于ASP .NET 4.5系列博文的第七篇文章。下一个版本的.NET和Visual Studio包括大量的新特性和新功能在开发ASP.NET 4.5 WebForms和Mvc的时候你会看到很多功能上的改进（不管是基于核心ASP.NET还是一些其他的扩展）在本篇文章中将会涵盖下一个版本的VisualStudio关于支持在ASP.NET中使用CSS3的一些改进CSS Color Picker在VisualStudio的早起版本中，CSS编辑器的智能提示引擎包括了一个颜色名称的下拉列表（硬编码）新版本的VisualStudio使用了一个功能齐全的颜色选择器可以很容易的创建新的颜色样式也</summary><published>2012-02-26T06:37:00Z</published><updated>2012-02-26T06:37:00Z</updated><author><name>liulun</name><uri>http://www.cnblogs.com/liulun/</uri></author><link rel="alternate" href="http://www.cnblogs.com/liulun/archive/2012/02/26/2368635.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/liulun/archive/2012/02/26/2368635.html"/><content type="html">&lt;p&gt;这是我所发的关于&lt;a href="http://weblogs.asp.net/scottgu/archive/2011/08/31/asp-net-vnext-series.aspx" target="_blank"&gt;ASP .NET 4.5系列&lt;/a&gt;博文的第七篇文章。&lt;/p&gt;&lt;p&gt;下一个版本的.NET和Visual Studio包括大量的新特性和新功能&lt;/p&gt;&lt;p&gt;在开发ASP.NET 4.5 WebForms和Mvc的时候&lt;/p&gt;&lt;p&gt;你会看到很多功能上的改进&lt;/p&gt;&lt;p&gt;（不管是基于核心ASP.NET还是一些其他的扩展）&lt;/p&gt;&lt;p&gt;在本篇文章中将会涵盖&lt;/p&gt;&lt;p&gt;下一个版本的VisualStudio关于支持在ASP.NET中使用CSS3的一些改进&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;CSS Color Picker&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在VisualStudio的早起版本中，&lt;/p&gt;&lt;p&gt;CSS编辑器的智能提示引擎包括了一个颜色名称的下拉列表（硬编码）&lt;/p&gt;&lt;p&gt;新版本的VisualStudio&lt;/p&gt;&lt;p&gt;使用了一个功能齐全的颜色选择器&lt;/p&gt;&lt;p&gt;可以很容易的创建新的颜色样式&lt;/p&gt;&lt;p&gt;也可以很容易的从样式表内选择其他地方使用过的颜色&lt;/p&gt;&lt;p&gt;当你使用CSS编辑器编辑一个CSS样式的颜色属性时&lt;/p&gt;&lt;p&gt;一个颜色拾色器将会自动出现&lt;/p&gt;&lt;p&gt;默认情况下&lt;/p&gt;&lt;p&gt;他显示了之前您使用过的颜色&lt;/p&gt;&lt;p&gt;以及一些推荐使用的颜色&lt;/p&gt;&lt;p&gt;你可以使用鼠标或者键盘在这个列表中选择一个颜色&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201202/201202261437115896.png" target="_blank"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201202/201202261437116735.png" alt="image" width="437" height="165" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;你可以选择&amp;rdquo;+&amp;rdquo;图标以展开一个更精细颜色选择列表&lt;/p&gt;&lt;p&gt;移动opacity（透明度）滑块，&lt;/p&gt;&lt;p&gt;可以控制alpha通道自动把任何颜色转化成CSS3 RGBA值&lt;/p&gt;&lt;p&gt;还有一个&amp;ldquo;颜色选择&amp;rdquo;功能&lt;/p&gt;&lt;p&gt;可以让你使用&amp;ldquo;吸管&amp;rdquo;工具从浏览器或其他应用程序中拾取颜色&lt;/p&gt;&lt;p&gt;（译者：造就该有这个功能了！）&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201202/20120226143711846.png" target="_blank"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201202/20120226143712780.png" alt="image" width="414" height="351" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;在这个&lt;a href="http://www.asp.net/web-forms/videos/visual-studio-vnext/visual-studio-vnext-videos-css-editor-color-picker" target="_blank"&gt;60秒的视频&lt;/a&gt;中，演示了颜色拾取器的使用方法&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;跨浏览器和CSS3片段&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;写样式表时，有时会有一些重复的工作，&lt;/p&gt;&lt;p&gt;经常会为不同版本的浏览器写兼容样式&lt;/p&gt;&lt;p&gt;在某些情况下需要写五个相同的值&lt;/p&gt;&lt;p&gt;为了支持所有的浏览器&lt;/p&gt;&lt;p&gt;必须做这些乏味的工作&lt;/p&gt;&lt;p&gt;在新版本的VisualStudio中&lt;/p&gt;&lt;p&gt;支持CSS片段，自动生成所有浏览器厂商的特定属性&lt;/p&gt;&lt;p&gt;这意味着没有更多繁琐的搜索和打字工作以使你的CSS兼容所有浏览器&lt;/p&gt;&lt;p&gt;css片段就像我们在VS中使用其他代码片段一样&lt;/p&gt;&lt;p&gt;（译者注：关于&lt;a href="http://www.cnblogs.com/anderslly/archive/2009/02/16/vs2008-code-snippets.html" target="_blank"&gt;CodeSnippet&lt;/a&gt;的内容，请参看这里）&lt;/p&gt;&lt;p&gt;例如：调用CSS3的transition属性&lt;/p&gt;&lt;p&gt;只要简单的输入&amp;ldquo;transition&amp;rdquo;或者从智能提示中选择此样式即可&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201202/201202261437126636.png" target="_blank"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201202/201202261437123256.png" alt="image" width="219" height="83" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;然后按tab键，VisualStudio会执行CSS的transition的代码片段&lt;/p&gt;&lt;p&gt;并生成相应的代码，以支持所有的浏览器！&lt;/p&gt;&lt;p&gt;并且可以只改一次样式值，就可以把所有选中值都改掉&lt;/p&gt;&lt;p&gt;（译者：真好啊！）&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201202/201202261437126603.png" target="_blank"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201202/201202261437138762.png" alt="image" width="397" height="168" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;点此观看&lt;a href="http://www.asp.net/web-forms/videos/visual-studio-vnext/visual-studio-vnext-videos-css-editor-snippets" target="_blank"&gt;关于CSS代码片段的六十秒视频&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;CSS层级缩进&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;现实中,开发网站的样式表代码时，&lt;/p&gt;&lt;p&gt;你会发现保持良好的缩进和层级关系已经成为一个趋势&lt;/p&gt;&lt;p&gt;一个树状的CSS样式&lt;/p&gt;&lt;p&gt;可以更好的体现样式之间的层级关系&lt;/p&gt;&lt;p&gt;和在样式属于哪些网页中的元素&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201202/20120226143713158.png" target="_blank"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201202/201202261437135141.png" alt="image" width="244" height="300" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;在VisualStudio的早期版本中&lt;/p&gt;&lt;p&gt;手动保持这些层级缩进是比较繁琐的工作&lt;/p&gt;&lt;p&gt;如果你格式化CSS代码（译者注：这里应该是指按快捷键ctl+e,d），&lt;/p&gt;&lt;p&gt;会清空所有的层级和缩进&lt;/p&gt;&lt;p&gt;这就要求你必须谨慎的使用代码格式化功能&lt;/p&gt;&lt;p&gt;在VisualStudio的下一个版本中，&lt;/p&gt;&lt;p&gt;加入了创建CSS的层级结构的功能&lt;/p&gt;&lt;p&gt;并且可以只格式化选中的内容&lt;/p&gt;&lt;p&gt;这使得审查复杂的样式关系和样式间的层级关系变得非常容易&lt;/p&gt;&lt;p&gt;VisualStudio中全新的CSS编辑器也支持常见的&lt;a href="http://www.webdevout.net/css-hacks" target="_blank"&gt;CSS&amp;nbsp; hack&lt;/a&gt;&lt;/p&gt;&lt;p&gt;这方面的内容也会体现在CSS的层级结构中&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201202/201202261437138173.png" target="_blank"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201202/201202261437139012.png" alt="image" width="306" height="314" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;关于&lt;a href="http://www.asp.net/web-forms/videos/visual-studio-vnext/visual-studio-vnext-videos-css-editor-hierarchial-indentation" target="_blank"&gt;CSS层级结构和60秒视频&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;小节&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在asp.net和VisualStudio的新版本中将更容易的使用CSS&lt;/p&gt;&lt;p&gt;这篇文章包括一些我们在VS上支持CSS编辑器的改进&lt;/p&gt;&lt;img src="http://www.cnblogs.com/liulun/aggbug/2368635.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/liulun/archive/2012/02/26/2368635.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/liulun/archive/2012/02/12/2347956.html</id><title type="text">【翻译】WCF4.5:更少的配置和ASP.NET更好的支持</title><summary type="text">原文地址：http://www.infoq.com/news/2012/02/WCF-4.5Ido Flatow发表了一些列的博客，来讲述.NET4.5中关于WCF的更新链接地址：http://blogs.microsoft.co.il/blogs/idof/archive/2011/10/05/what-s-new-in-wcf-4-5-automatic-https-endpoint-for-iis.aspx（有时间的话我会陆续翻译）出于削减复杂性的目的，WCF自动生成的配置文件将会变得非常、非常的小。自从第一个版本的WCF以来，开发人员发现他们需要维护一个大概有30个配置节的app.co</summary><published>2012-02-12T06:40:00Z</published><updated>2012-02-12T06:40:00Z</updated><author><name>liulun</name><uri>http://www.cnblogs.com/liulun/</uri></author><link rel="alternate" href="http://www.cnblogs.com/liulun/archive/2012/02/12/2347956.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/liulun/archive/2012/02/12/2347956.html"/><content type="html">&lt;p&gt;原文地址：&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.infoq.com/news/2012/02/WCF-4.5" target="_blank"&gt;http://www.infoq.com/news/2012/02/WCF-4.5&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Ido Flatow发表了一些列的博客，来讲述.NET4.5中关于WCF的更新&lt;/p&gt;&lt;p&gt;链接地址：&lt;/p&gt;&lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/idof/archive/2011/10/05/what-s-new-in-wcf-4-5-automatic-https-endpoint-for-iis.aspx" target="_blank"&gt;http://blogs.microsoft.co.il/blogs/idof/archive/2011/10/05/what-s-new-in-wcf-4-5-automatic-https-endpoint-for-iis.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;（有时间的话我会陆续翻译）&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;出于削减复杂性的目的，WCF自动生成的配置文件将会变得非常、非常的小。自从第一个版本的WCF以来，开发人员发现他们需要维护一个大概有30个配置节的app.config文件，而这些配置节都可以用默认值来代替。谁都知道删除这些多余的设置比较好,但不幸的是，谁都没有学会这一招！在WCF 4.5中配置文件只需要设置绑定的类型和名称即可！&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;当然这导致了另一个问题：&amp;ldquo;我怎么知道这些设置是什么呢？&amp;rdquo;为了回答这个问题，我们必须知道配置文件后端的代码（与配置信息相关的代码），并且配置文件的提示并不在是基于schema的智能提示。如果你正在编辑一个endpoint，你需要知道一个behavior的名字，这个时候开发工具会把可用的behavior的名字都给你列出来。在编译时一些配置文件的错误，如契约类型(contract type)行为名称(behavior name)的错误都会被提示出来。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;对于那些直接使用WSDL的开发人员来说，也有好消息。WCF 4.5将会在一个单独的请求中返回一个完整的WSDL。在此之前，只会包含一部分WSDL，这将需要一系列的XSD文件来匹配这个WSDL。使用?singleWsdl查询字符串取代?singleWsdl可以使用这个改进&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;把WCF服务寄宿到&lt;a href="http://en.wikipedia.org/wiki/Windows_service" target="_blank"&gt;系统服务&lt;/a&gt;内是完全可行的。但大多数开发人员继续在IIS下完成大量的工作。为什么呢？因为IIS提供了很多内置的支持功能，比如身份验证，状态管理和进程回收等。但在IIS下开发WCF服务仍然有一些限制，微软也正在解决这些问题。比如：必须通过配置才能解决在两个地方的身份认证服务，如果他们由于异常而没有同步，那么这个WCF服务就会停止运行。WCF4.5通过允许服务按IIS的方式来进行身份认证（设置身份认证的方式为&amp;ldquo;继承自宿主InheritedFromHost&amp;rdquo;）除掉了此类型的BUG&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;不幸的的是这只是一个局部修复，如果IIS激活了多个身份验证类型，那么客户端只会知道第一个。当然客户端开发人员会找到另一种方法解决这个问题：他们可以使用另一种类型重写这个身份验证类型。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;在为基于HTTPS的服务构造URIs对象时，在WSDL信息中显示了一个BUG，在.net 4中WCF有自动选择端口的特性（针对各种类型的绑定，TCP,HTTP等）不幸的是，HTTPS在那是还没有被包括进来。在.NET4.5中这些疏忽将被纠正。Ido Flatow认为HTTPS 版本是在为主机名做广告而不是访问WSDL的宿主名（host name），这些可能将成为使用web form时的问题。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;另一个bug是关于WCF传输流数据的，Ido Flatow:&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;当你把WCF服务寄宿在IIS上时，即使你没有使用asp.net兼容模式，你也一样会得到asp.net处理管线的一部分。可以在MSDN文档：&lt;a href="http://msdn.microsoft.com/en-us/library/aa702682.aspx" target="_blank"&gt;WCF服务和ASP.NET&lt;/a&gt;（查找PostAuthenticateRequest Event部分）找到相关内容。在.Net 4中，ASP.NET里有一个设计缺陷，对WCF的请求会在ASP.NET中缓冲，这些缓冲行为会引起一些副作用&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;这不仅仅造成处理请求的延时，更严重的是，相当大的一部分内容溢出到硬盘上了。&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #000000;"&gt;在WCF 4.5中解决了这个问题。&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/liulun/aggbug/2347956.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/liulun/archive/2012/02/12/2347956.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/liulun/archive/2012/02/05/2338892.html</id><title type="text">【翻译】在没有安装ASP.NET MVC3的服务器上运行ASP.NET MVC3的程序-scottgu</title><summary type="text">原文地址：http://weblogs.asp.net/scottgu/archive/2011/01/18/running-an-asp-net-mvc-3-app-on-a-web-server-that-doesn-t-have-asp-net-mvc-3-installed.aspx为了更符合中文阅读习惯，我对原文做了小幅度修改最近我们发布了一些新的Web产品 - 包括ASP.NET MVC 3。至今为止，我们已经获得了大量的反馈。有几个朋友在问我一个问题：“我的网站托管服务提供商目前还不支持ASP.NET MVC 3 - 你知道他们将来什么时候会安装吗？”好消息是，您不必等他们在We</summary><published>2012-02-05T04:16:00Z</published><updated>2012-02-05T04:16:00Z</updated><author><name>liulun</name><uri>http://www.cnblogs.com/liulun/</uri></author><link rel="alternate" href="http://www.cnblogs.com/liulun/archive/2012/02/05/2338892.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/liulun/archive/2012/02/05/2338892.html"/><content type="html">&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;原文地址：&lt;/p&gt;&lt;p&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2011/01/18/running-an-asp-net-mvc-3-app-on-a-web-server-that-doesn-t-have-asp-net-mvc-3-installed.aspx" target="_blank"&gt;http://weblogs.asp.net/scottgu/archive/2011/01/18/running-an-asp-net-mvc-3-app-on-a-web-server-that-doesn-t-have-asp-net-mvc-3-installed.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;为了更符合中文阅读习惯，我对原文做了小幅度修改&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;最近我们发布了一些新的&lt;a href="http://weblogs.asp.net/scottgu/archive/2011/01/13/announcing-release-of-asp-net-mvc-3-iis-express-sql-ce-4-web-farm-framework-orchard-webmatrix.aspx" target="_blank"&gt;Web产品&lt;/a&gt; - 包括&lt;a href="http://weblogs.asp.net/scottgu/archive/2011/01/13/announcing-release-of-asp-net-mvc-3-iis-express-sql-ce-4-web-farm-framework-orchard-webmatrix.aspx" target="_blank"&gt;ASP.NET MVC 3&lt;/a&gt;。至今为止，我们已经获得了大量的反馈。&lt;/p&gt;&lt;p&gt;有几个朋友在问我一个问题：&amp;ldquo;我的网站托管服务提供商目前还不支持ASP.NET MVC 3 - 你知道他们将来什么时候会安装吗？&amp;rdquo;&lt;/p&gt;&lt;p&gt;好消息是，您不必等他们在Web服务器上安装ASP.NET MVC3。&lt;/p&gt;&lt;p&gt;只要您的网站托管服务提供商支持.NET 4，那么您现在就可以构建和部署ASP.NET MVC3应用程序了&lt;/p&gt;&lt;p&gt;- 不用托管供应商做任何事。&lt;/p&gt;&lt;p&gt;下面的文章介绍如何启用此功能。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;&lt;strong&gt;一些背景：&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;我们支持两种方式使您可以使用一台机器上的ASP.NET MVC3组件：&lt;br /&gt;1，在一台机器上，将ASP.NET MVC 3组件安装在一个集中的地方，WEB项目在那里引用这些组件&lt;/p&gt;&lt;p&gt;2，把ASP.NET MVC 3的组件复制到您的Web项目的\bin文件夹下，WEB项目在那里引用这些组件&lt;/p&gt;&lt;p&gt;第一种方法是我们使用Visual Studio中使用的默认方法，&lt;/p&gt;&lt;p&gt;这使得我们可以更容易为ASP.NET MVC 3提供升级服务（当发现BUG的时候）。&lt;/p&gt;&lt;p&gt;第二种方法也是得到了完全支持，没有在服务器上安装ASP.NET MVC3，也可以使用它。&lt;/p&gt;&lt;p&gt;你只要把ASP.NET MVC的组件放在你的WEB程序的bin目录中，然后把整个Web程序拷贝到FTP（WEB服务器）上，它就可以工作了。&lt;/p&gt;&lt;p&gt;如果您的网站托管服务提供商还没有在他们的服务器上安装ASP.NET MVC 3，那么您应该使用第二种方法。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;&lt;strong&gt;方法1：基于GAC引用ASP.NET MVC组件&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;当您在计算机上安装ASP.NET MVC 3的时候，&lt;/p&gt;&lt;p&gt;一些组件会自动注册到&lt;a href="http://en.wikipedia.org/wiki/Global_Assembly_Cache" target="_blank"&gt;GAC&lt;/a&gt;中（全局程序集缓存）。&lt;/p&gt;&lt;p&gt;GAC提供一个集中的地方供安装和升级（通过Windows更新）.NET程序集。&lt;/p&gt;&lt;p&gt;因此ASP.NET MVC3项目默认在这里引用程序集。&lt;/p&gt;&lt;p&gt;如果你复制一个普通的ASP.NET MVC 3项目（使用默认的方法引用ASP.NET MVC3的程序集）&lt;/p&gt;&lt;p&gt;到一台没有安装ASP.NET MVC3的机器上，&lt;/p&gt;&lt;p&gt;当你运行应用程序时，&lt;/p&gt;&lt;p&gt;会看到一个类似的错误信息：&lt;/p&gt;&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/scottgu/image_64EB2E92.png" target="_blank"&gt;&lt;img title="image" src="http://weblogs.asp.net/blogs/scottgu/image_thumb_2A2385BC.png" alt="image" width="735" height="301" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;上述错误表示，&lt;/p&gt;&lt;p&gt;至少有一个运行ASP.NET MVC 3所需的程序集在GAC中找不到。&lt;/p&gt;&lt;p&gt;在机器上安装ASP.NET MVC 3就能解决这个问题，&lt;/p&gt;&lt;p&gt;让您的应用程序正常运行。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style="color: #ff0000;"&gt;&lt;strong&gt;方法2：基于\ Bin目录中引用ASP.NET MVC组件&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;您的项目可以使用另一种方法&lt;/p&gt;&lt;p&gt;在您的Web应用程序的\bin目录中分发和引用的ASP.NET MVC3的程序集。&lt;/p&gt;&lt;p&gt;这种方法的好处是，你并不需要在一台机器上安装ASP.NET MVC3，以运行基于ASP.NET MVC3 Web应用程序。&lt;/p&gt;&lt;p&gt;相反，你只要复制你的web应用程序（在bin目录中包含MVC3的组件）到 .NET4服务器上，它就会运行。&lt;/p&gt;&lt;p&gt;这种方法是&amp;ldquo;完全信任&amp;rdquo;，&amp;ldquo;中等信任&amp;rdquo;的情景 （&lt;em&gt;译注：我也不知道是什么意思&lt;/em&gt;）&lt;/p&gt;&lt;p&gt;这意味着它甚至可以和低成本共享主机供应商共事。&lt;/p&gt;&lt;p&gt;无需托管服务提供商另外注册/安装/操作需要。&lt;/p&gt;&lt;p&gt;使您的Web项目包含ASP.NET MVC3程序集&amp;ldquo;bin部署&amp;rdquo;是非常简单的，&lt;/p&gt;&lt;p&gt;只需2分钟左右。下面是需要遵循的步骤：&lt;/p&gt;&lt;p&gt;&lt;a href="http://drew-prog.blogspot.com/2011/01/how-to-deploy-aspnet-mvc-3-app-to-web.html" target="_blank"&gt;Steps to Deploy an ASP.NET MVC 3 Application to a Web Hosting Provider with \Bin deployment&lt;/a&gt;&lt;/p&gt;&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;p&gt;译注：这个链接好像打不开，笔者提供一个方法：&lt;/p&gt;&lt;p&gt;选中ASP.NET MVC引用的程序集，然后查看属性，把&amp;ldquo;复制到本地&amp;rdquo;修改为true&lt;/p&gt;&lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201202/201202051216232315.png" target="_blank"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201202/201202051216242348.png" alt="image" width="350" height="517" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;asp.net mvc3需要的程序集有&lt;/p&gt;&lt;ul&gt;&lt;li&gt;System.Web.Mvc&lt;/li&gt;&lt;li&gt;Microsoft.Web.Infrastructure&lt;/li&gt;&lt;li&gt;System.Web.Razor&lt;/li&gt;&lt;li&gt;System.Web.WebPages&lt;/li&gt;&lt;li&gt;System.Web.WebPages.Razor&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;一旦配置\BIN部署后，&lt;/p&gt;&lt;p&gt;您使用ASP.NET MVC 3构建的应用程序将在任何安装.NET4的Web服务器上工作。&lt;/p&gt;&lt;p&gt;只需复制到Web服务器，它就会运行。&lt;/p&gt;&lt;p&gt;即使是低成本共享托管账户，你也无需托管服务供应商做任何事。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;找一个ASP.NET MVC 3网站托管服务提供商&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;您可以浏览&lt;a href="http://www.microsoft.com/web/hosting/home" target="_blank"&gt;Windows Web Hosting Gallery&lt;/a&gt;（Windows网站托管库）找到所有支持托管服务提供商：&lt;br /&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/liulun/201202/201202051216243253.png" target="_blank"&gt;&lt;img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" src="http://images.cnblogs.com/cnblogs_com/liulun/201202/201202051216252480.png" alt="image" width="508" height="424" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Windows网站托管库允许您通过不同国家和服务水平来筛选/浏览托管服务。&lt;/p&gt;&lt;p&gt;它还能让您轻松过滤&amp;ldquo;共享主机&amp;rdquo;，&amp;ldquo;虚拟主机&amp;rdquo;和&amp;ldquo;专用主机&amp;rdquo;供应商。&lt;/p&gt;&lt;p&gt;&amp;ldquo;共享主机&amp;rdquo;是指在你没有管理员权限的远程服务器上，提供单一的Web服务器。&lt;br /&gt;&amp;ldquo;虚拟主机&amp;rdquo;供应商在一个远程服务器上提供给你虚拟机 - 通常通过操作系统管理权限和管理的远程终端服务器来访问。&lt;/p&gt;&lt;p&gt;&amp;ldquo;专用主机&amp;rdquo;供应商提供您一个完整的物理服务器，通常也提供操作系统的管理员权限和远程终端支持。&lt;/p&gt;&lt;p&gt;基于Windows的网络托管的价格现在是非常符合成本效益的，&lt;/p&gt;&lt;p&gt;共享主机低至$2.75/月，虚拟主机提供的报价$23/月。&lt;/p&gt;&lt;p&gt;上述主机都能通过使用\ bin部署方法来运行ASP.NET MVC 3。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;span style="color: #ff0000;"&gt;摘要&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;ASP.NET MVC 3的应用程序可以部署到任何拥有.NET4的Web服务器，&lt;/p&gt;&lt;p&gt;而不必等待托管服务提供商来安装ASP.NET MVC 3组件。&lt;/p&gt;&lt;p&gt;通过\ bin部署ASP.NET MVC3程序集，&lt;/p&gt;&lt;p&gt;只需使用上面的步骤就可转换您的项目，&lt;/p&gt;&lt;p&gt;那么你就可以复制你的应用程序到任何ASP.NET4服务器上。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/liulun/aggbug/2338892.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/liulun/archive/2012/02/05/2338892.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
