博客堂 Enjoy coding, Enjoy Life!

【第1页/共736页,7360条】
首页
前页
1
...

SharePoint服务器连接配置数据库的连接字符串保存在哪里?

经常有人问我这个问题,SharePoint服务器将连接配置数据库的连接字符串保存在什么地方?虽然其他SharePoint服务器场设置都是保存到了配置数据库里面,但连接配置数据库本身的连接字符串,肯定是只能存放在SharePoint服务器上的。

简单来说,SharePoint服务器将这个连接字符串信息保存在注册表中,具体位置是在"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0\Secure\ConfigDB"节点的"dsn"键值中。

image 

提示:在注册表里面进行更改,是不被微软正式Support的,所以不要尝试做这样的操作!

posted on 2010-02-09 16:06:13 by kaneboy  评论(0) 阅读(142)

为SharePoint 2010创建Application Page

如果不了解什么是Application Page,可以参考我以前写过的这篇文章。SharePoint 2010的页面模型没有太多的变化,基本和2007保持一致。对于开发人员而言,为SharePoint 2010创建一个Application Page,相比2007倒是方便了很多,因为Visual Studio 2010提供了很好的工具支持。

如下图所示,开发人员可以直接在一个SharePoint项目中添加一个Application Page:
image

在SharePoint 2010中,自定义Application Page默认仍然是从Microsoft.SharePoint.WebControls.LayoutsPageBase类继承而来:
image 

除了在工具上的支持之外,SharePoint 2010的Application Page也已经可以使用网站公用的Master Page了,这意味着在设计师为网站设计了一个自定义的Master Page之后,Application Page也能呈现出与网站内容页面一致的效果了。

如下图所示,通过指定Application Page页面的<@ Page>标签中的"DynamicMasterPageFile"属性(注意不是"MasterPageFile")的值,就能让Application Page直接使用用户当前所浏览网站的Master Page。
image 

"DynamicMasterPageFile"属性的值可以是:
■ "~masterurl/default.master":表示将使用SPWeb.MasterUrl属性所标识的Master Page,默认是网站母板页样式库中的"v4.master"文件。
■ "~masterurl/custom.master":表示将使用SPWeb.CustomMasterUrl属性所标识的Master Page,默认它和SPWeb.MasterUrl的值保持一致,都是引用的"v4.master"。

如果你仍然希望让Application Page使用"14\templates\_layouts"目录下的"application.master"或"applicationv4.master",那么不要使用"DynamicMasterPageFile"属性,而仍然应该使用"MasterPageFile"属性。

虽然通过Application Page的"DynamicMasterPageFile"属性能让Application Page使用网站的Master Page,但系统管理员也可以取消这项设定。在SharePoint 2010管理中心的Web应用程序管理中,通过将下图所示的选项设置为“否”,就能让Application Page不能引用网站的Master Page:
image

当然也可以通过Object Model来完成同样的操作:
image 

如果通过上面的这两个方法,不允许Application Page使用网站的Master Page,同时又在"<@ Page>"中指定了"DynamicMasterPageFile"属性,那么Application Page会在"14\templates\layouts"目录中寻找"v4.master"。

最后,下面这几个特殊的Application Page,由于它们可能需要在任何场合(比如在用户没有通过认证的情况下)下被显示,所以它们都会使用"simple.master"这个最简Master Page:
■ Login.aspx
■ SignOut.aspx
■ Error.aspx
■ ReqAcc.aspx
■ Confirmation.aspx
■ WebDeleted.aspx
■ AccessDenied.aspx

posted on 2010-02-08 03:03:27 by kaneboy  评论(1) 阅读(818)

ASP.NET MVC 2博客系列之二:模型验证

【原文地址】ASP.NET MVC 2: Model Validation
【原文发表日期】 Friday, January 15, 2010 4:14 AM

除了写博客外,我现在还使用Twitter发短贴和共享链接。请通过twitter.com/scottgu跟随我。

这是我针对即将发布的ASP.NET MVC 2所撰写的贴子系列的第二篇,这个博客贴子将讨论 ASP.NET MVC 2中一些验证方面的改进。

ASP.NET MVC 2 验证

对用户输入的验证以及强制业务规则/逻辑是大多数web应用的核心需求。ASP.NET MVC 2包含了一堆新的特性,显著地简化了对用户输入的验证以及在模型/视图模型中对验证逻辑的强行实施。这些特性是这样设计的,验证逻辑总是在服务器上执行的,也可以选择在客户端通过JavaScript来执行。ASP.NET MVC 2中的验证设施和特性这般设计,以便:

1) 开发人员可以轻易地利用内置于.NET框架中的DataAnnotation验证支持。DataAnnotation提供了一个非常简便的方式,使用最少的代码在对象和属性上用声明的方式添加验证规则。

2) 开发人员可以集成他们自己的验证引擎,或者利用现有的验证框架,象Castle验证器或EntLib验证库。ASP.NET MVC 2的验证特性是设计来在利用新的 ASP.NET MVC 2的验证设施(包括客户端验证,模型绑定验证等等)的同时,简化任何类型的验证架构的插入的。

这意味着,在常见的应用场景中启用验证是极其容易的,同时对更高级的场景则还能保持极好的灵活性。

使用ASP.NET MVC 2 和 DataAnnotation来启用验证

让我们在ASP.NET MVC 2中来全程示范一个简单的CRUD场景,利用新的内置DataAnnotation验证支持。具体来说,让我们来实现一个“Create”表单来允许用户输入朋友的数据:

image

我们想要确保在保存到数据库之前,输入的信息是合法的,如果不合法,就显示合适的错误消息:

image

我们想要使得这个验证同时在服务器端和客户端(通过 JavaScript)发生。我们还想要确保我们的代码遵守DRY原则(Don't Repeat Yourself,不重复自己),意味着我们应该只在一处实施验证规则,然后使得我们的控制器,action方法和视图来兑现这个承诺。

在下面,我将使用VS 2010,用ASP.NET MVC 2来实现上面的场景。你也可以使用VS 2008及ASP.NET MVC 2来实现完全一样的场景。

第一步: 实现FriendsController (一开始没有验证)

我们首先在一个新的ASP.NET MVC 2项目中加一个简单的“Person”类,象下面这样:

image

它有四个属性(是用C#的自动属性支持实现的, 在VS 2010中VB也支持自动属性了,哎!)。

然后在项目中加一个 “FriendsController” 控制器类,呈示2个 “Create” action方法。第一个action方法是在对/Friends/Create URL的HTTP-GET请求进来时调用的,它会显示一个空白的表单,用来输入个人数据。第二个action方法是在对/Friends/Create URL的HTTP-POST请求进来时调用的。它会将提交的表单输入映射到一个Person对象,核实没有绑定错误发生,如果是合法的,最终会将数据保存到数据库中去(在本教程的后面我们会实现相关的数据库工作)。如果提交的表单输入是不合法的,该action方法会重新显示带有错误的表单:

image

在实现了控制器之后,可以在Visual Studio中在其中一个action方法中右击,选择 “添加视图”命令, 这会调出 “添加视图” 对话框。选择自动生成传入对象为Person的“Create”视图:

image

然后Visual Studio会在我们项目的\Views\Friends\目录中,生成一个含有框架代码(scaffolded)的Create.aspx视图文件。注意下面,它利用了ASP.NET MVC 2中新的强类型HTML辅助方法(促成了更好的intellisense和编译时检查支持):

image

现在,当我们运行该应用,访问 /Friends/Create URL时,我们将得到一张可以输入数据的空白表单:

image

但,因为我们还没有在应用中实现任何验证,谁也无法阻止我们在表单中键入假的输入,将其提交到服务器去。

第二步: 使用DataAnnotation来启用验证

现在,让我们来更新应用,执行一些基本的输入验证规则。我们将在我们的Person模型对象上实现这些规则,而不是在控制器或视图中实现。在Person对象上实现这些规则的好处是,这将确保这些验证在应用中任何使用Person对象的场景中都会被执行(例如,如果后来添加了编辑场景的话)。这将帮助确保我们将代码保持DRY,避免在多处重复这些规则。

ASP.NET MVC 2 允许开发人员轻松地在模型或视图模型类上添加声明式验证特性,然后ASP.NET MVC在应用中实施模型绑定操作时,这些验证规则就会被自动执行。为看其例子,让我们更新Person类,在其中加几个验证特性。这么做,在文件的顶部加一个对“System.ComponentModel.DataAnnotations”命名空间的 “using” 语句,然后在Person的属性上饰于[Required], [StringLength], [Range], 和 [RegularExpression] 验证特性(这几个特性都是在那个命名空间中实现的):

image

注: 在上面我们明式指定了错误信息字符串,你也可以在资源文件中定义它们,或者按进来的用户的语言/文化做本地化,你可以在这里了解如何本地化验证错误消息。

既然我们加了验证特性到Person类上,让我们来重新运行我们的应用,看在键入假的数值,将其提交回服务器时会发生什么:

image

注意上面我们的应用现在有一个蛮好的出错体验了。带不合法输入的文本元素以红色高亮显示,我们指定的验证错误消息也显示给了用户。表单还保留用户原先输入的数据,这样他们不用重新填写什么。但,你也许会问,怎么会是这样?

要理解这个行为,让我们看一下处理我们表单的POST场景的Create action方法:

image

在我们的HTML表单被提交回服务器时,上面的方法就会被调用。因为该action方法接受一个“Person” 对象为参数,ASP.NET MVC会创建一个Person对象,自动地将进来的表单输入数值映射到该对象上。作为该过程的一部分,ASP.NET MVC还会检查该Person对象上的DataAnnotation验证特性是否合法。如果一切都合法,那么我们代码中的ModelState.IsValid检查就会返回真值,在这种情形下,我们(最终)将把该Person对象保存到数据库中,然后重新定向回到主页上去。

但如果Person对象上有任何验证错误的话,我们的action方法就会以该不合法Person对象的数据重新显示表单,这是通过上面代码片段中最后一行代码实现的。

然后,错误消息就会显示在我们的视图中,因为我们的Create表单在每一个<%= Html.TextBoxFor() %>辅助方法的调用旁边都有一个<%= Html.ValidationMessageFor() %>辅助方法调用。Html.ValidationMessageFor() 辅助方法会针对传入视图的任何不合法的模型属性输出合适的错误消息:

image

这个模式/方式有一个好处,就是非常容易配置,它还允许我们轻松地添加或改变我们Person类上的验证规则,而不必改变控制器或视图中的任何代码。这个在一个地方指定验证规则,然后在所有的地方都会被承诺和遵守的能力,允许我们以最少的努力快速地发展我们的应用和规则,并且将代码保持在非常DRY的程度。

第三步: 启用客户端验证

目前我们的应用只能做服务器端的验证,这意味着我们的终端用户需要将表单提交到服务器才能看到任何验证错误消息。

ASP.NET MVC 2的验证架构中一样非常酷的东西是,它同时支持服务器端 客户端验证。为启用这个功能,我们要做的就是在视图中添加2个 JavaScript引用,编写一行代码:

image

在我们添加了这三行后,ASP.NET MVC 2 就会使用我们加到Person类上的验证元数据,为我们连接好客户端JavaScript验证逻辑。这意味着,当用户使用tab键跳出一个不合法的输入元素时,就会得到瞬时的验证错误。

要在我们的朋友应用中看客户端JavaScript支持的实战例子的话,让我们重新运行应用,在前三个文本框中填入合法的数值,然后尝试点击“Create(创建)”。注意,我们不必访问服务器就会得到遗漏值的瞬时错误消息:

image

如果我们输入一些不是合法的email的字符话,错误消息就会瞬时从“Email Required (Email是个必需值)” 变为 “Not a valid email (email不合法)”(这是我们将规则加到Person类上时指定的错误消息):

image

在输入一个合法的email时,错误消息就是瞬时消失,文本框背景色也会恢复到正常的状态:

image

好事是,我们不必编写自己的任何定制JavaScript就能启用上面的验证逻辑。我们的验证代码还是那么DRY,我们可以在一个地方指定规则,然后在整个应用中得到执行,同时在客户端和服务器端。

注意,为安全的原因,服务器端验证规则总是执行的,即时你启用了客户端支持。这避免黑客尝试绕过客户端规则,哄骗攻击(spoof)你的服务器。

ASP.NET MVC 2中的客户端JavaScript验证支持可与你在ASP.NET MVC应用中使用的任何验证框架/引擎协作,它并不要求你使用 DataAnnotation 验证方式,所有的基础设施是独立于 DataAnnotation的,可以与Castle验证器, EntLib验证应用块,或你选择使用的任何定制验证方案协作使用。

如果你不想使用我们的客户端JavaScript文件,你也可以将其替换成jQuery验证插件,而使用那个库。 ASP.NET MVC Futures下载还包括针对ASP.NET MVC 2服务器端验证框架启用jQuery验证的支持。

第四步: 创建自定义的[Email]验证特性

.NET框架中的System.ComponentModel.DataAnnotations命名空间包括了众多可为你所用的内置验证特性。我们在上面的例子中使用了其中的四个:[Required], [StringLength], [Range], 和 [RegularExpression]。

你也可以定义自己的定制验证特性,然后应用它们。你可以通过继承自System.ComponentModel.DataAnnotations命名空间中的ValidationAttribute基类,定义完全定制的特性。或者,你也可以选择继承自任何现有的验证特性,如果你只想要扩展它们的基本功能的话。

例如,为帮助清理我们Person类中的代码,我们也许想要创建一个新的[Email]验证特性,将检查合法email的正则表达式封装起来。要这么做的话,我们只要象这样继承自RegularExpressionAttribute基类,然后用合适的email正则表达式调用RegularExpressionAttribute基类的构造器:

image

然后将Person类更新成使用我们新的[Email]验证属性,换掉我们先前使用的正则表达式,这使得我们的代码更干净,封装也更好:

image

在创建定制的验证特性时,你还可以指定在服务器端以及在客户端通过JavaScript执行的验证逻辑。

除了创建可施用于对象上个别属性的验证特性外,你还可以将验证特性施用于类的层次,这允许你对一个对象中的多个属性实施验证逻辑。要看实战例子的话,你可以参阅包含在默认ASP.NET MVC 2应用项目模板中AccountModels.cs/vb文件中的“PropertiesMustMatchAttribute” 定制特性(在VS 2010中做 文件->新ASP.NET MVC 2 Web项目,然后查询该类)。

第五步: 持久化到数据库中

现在让我们来实现将朋友数据保存到数据库所需的逻辑。

image 

至此,我们只用了平白的(plain-old)C#类(有时称为“POCO” 类, 即 “plain old CLR (or C#) object”)。我们可以使用的一个方案是,编写一些单独的持久代码,将这我们已经编写好的现有类映射到数据库去。目前象NHibernate这样的对象关系映射(Object relational mapping - ORM)方案非常地好支持这样的POCO/PI风格的映射。随.NET 4发布的ADO.NET实体框架(Entity Framework - EF)也支持POCO / PI映射,而且就象NHibernate,EF也能启用以“只用代码(code only)”的方式(没有映射文件,也不需要设计器)定义持久性映射的能力。

如果我们的Person对象以这种方式映射到数据库的话,我们不用对Person类做任何改动,也不用改动任何验证规则,它还会继续完好地工作。

但假如我们要使用图形工具来做ORM映射的话,怎么办?

今天使用Visual Studio的许多开发人员并不编写他们自己的ORM映射/持久逻辑,而是使用Visual Studio中内置的设计器来帮助管理这样的映射逻辑。

使用DataAnnotation(或者任何其他形式的基于特性的验证)时一个经常问起的问题是,“如果你手头的模型对象是由GUI设计器创建/维护的话,你该如何施用这些特性?”。例如,假如与类似我们至此为止一直在使用的POCO风格的Person类不同,我们而是在Visual Studio中通过象LINQ to SQL 或 ADO.NET EF设计器这样的GUI映射工具定义/维护我们的Person类的话,该怎么办呢:

image

上面是一张屏幕截图,展示了在VS 2010中使用ADO.NET EF设计器定义的一个Person类。上方的窗口定义了Person类,下方的窗口展示了该类的属性是如何映射到数据库中的“People”表的映射编辑器。当你在设计器上点击保存时,它会自动为你在项目中生成一个Person类。这很棒,但每次你做了改动,点击保存时,它就会重新生成 Person 类,这会导致你在对象上面声明的任何验证特性的丢失。

将额外的基于特性的元数据(象验证特性)施加到由VS设计器自动生成/维护的类的一个方法是,采用一个我们称之为“伙伴类(buddy classes)”的技术。基本上来说,你创建另外一个类,包含你的验证特性和元数据,然后通过将 “MetadataType”特性施加到一个与工具生成的类一起编译的partial类上,将其与由设计器生成的类连接起来。例如,如果我们想要将我们前面用到的验证规则施加到由LINQ to SQL 或 ADO.NET EF设计器维护的Person类上,我们可以更新我们的验证代码,使其存在于一个单独的“Person_Validation”类上,使用象下面这样的代码将其连接到由VS创建的“Person”类上:

image

上面的做法没有纯粹的POCO方法那么优雅,但其好处是,可以用于Visual Studio中任何工具或设计器生成的代码。

最后一步 – 将Friend保存到数据库中

最后一步,不管是否采用了POCO或工具生成的Person类,是将合法的朋友数据保存到数据库中去。

这只要求我们用三行代码将FriendsControlle类中的 “Todo”占位语句替换掉,这三行代码将新朋友保存到数据库。下面是整个FriendsController类的完整代码(使用了ADO.NET EF做数据库持久化):

image

现在,当我们访问 /Friends/Create URL时,我们可以轻松地添加新人到我们的朋友数据库中去:

image

对所有数据的验证都是同时在客户端和服务器端执行的。我们可以轻易地在一个地方添加/修改/删除验证规则,而由整个应用中的所有的控制器和视图来执行这些规则。

结语

ASP.NET MVC 2极大地简化了web应用的验证集成。它倡议一种基于模型的验证方式,允许你将你的应用保持DRY,帮助确保验证规则在整个应用中保持一致。ASP.NET MVC 2中内置的DataAnnotation支持,原本就使得对常见的验证场景的支持非常容易。而且,ASP.NET MVC 2验证设施中的扩展性支持允许你支持更大范围的更高级的验证场景,可以插入任何现有的或者定制的验证框架/引擎。

希望本文对你有所帮助,

Scott

posted on 2010-02-08 01:03:56 by scottgu  评论(0) 阅读(1119)

WPF/Silverlight 控件的几幅继承关系图

图均来自网络,如下,这几幅图对理解控件的继承关系很有帮助:

image_3

DispatcherObject: WPF/Silverlight 中有许多类继承自DispatcherObject,DispatcherObject提供了处理同步和并发的基本构造。

DependencyObject :构建WPF/Silverlight的一个主要思想是属性优先于方法和事件。WPF/Silverlight 提供了丰富的属性系统,其核心是DependencyObject。

Visual:该类的主要作用是为WPF/Silverlight 提供2D呈现支持,主要包括输出显示,坐标转换,区域剪切等。

UIElement:该类继承自Visual类,是构建WPF/Silverlight元素和基本呈现特征的基类,其中定义很多与输入和焦点有关的特性,例如键盘事件,鼠标,还包括一些与WPF事件模型有关的API。

FrameworkElement:继承了UIElement类,而且还添加了一些功能,例如,布局定义、逻辑树、对象生命周期事件、支持数据绑定和动态资源引用、支持样式和动画。

image3

Control是创建自定义应用程序控件的基类。可以重写Control类所提供的属性,方法,事件等,为自定义控件添加自定义逻辑。 构建WPF/Silvlerlight  应用程序页面的window类就派生自它.还有button,TextBox等控件也派生自他。

Shape:WPF/Silvlerlight 中呈现二维矢量图形的基础类。有 Line、Polyline、Polygon、Path、Rectangle 和 Ellipse等子类。可从 Shape 类进行派生以实现自定义矢量图形基元。从 Shape 派生是确保这些自定义基元使用 WPF/Silvlerlight 布局系统的协议的最简单方法。

posted on 2010-02-07 18:01:30 by ghj1976  评论(1) 阅读(719)

DependencyProperty

和传统属性的区别在哪里,为什么要搞出这样一个DependencyProperty呢?

  • 内存使用量。
    我们设计控件,不可避免的要设计很多控件的属性,高度,宽度等等,这样就会有大量(私有)字段的存在,一个继承树下来,低端的对象会无法避免的膨胀。而外部通过GetValue,SetValue暴露属性,内部维护这样一个EffectiveValueEntry的数组,顾名思义,只是维护了一个有效的、设置过值的列表,可以减少内存的使用量。
  • 传统属性的局限性。
    这个有很多,包括一个属性只能设置一个值,不能得到变化的通知,无法为现有的类添加新的属性等等。

在 MSDN 中,提到当你有下面四种情况时,应该考虑使用DependencyProperty:

  • 您希望可在样式中设置此属性。
  • 您希望此属性支持数据绑定。
  • 您希望此属性支持经过动画处理的值。
  • 您希望 Silverlight 属性系统在属性系统本身、环境或用户执行的操作或者读取并使用样式而更改了属性以前的值时进行报告。您的属性可以指定在每次属性系统确定属性值已被明确更改时将调用的回调方法。

 

一个Silverlight中创建 DependencyProperty 的例子

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;

namespace SilverlightApplication2
{
    public partial class SilverlightControl1 : UserControl
    { 

        /// <summary>
        /// Declare the dependency property as static, readonly field in your class.    
        /// </summary>
        public static readonly DependencyProperty AquariumGraphicProperty 
            = DependencyProperty.Register(
          "AquariumGraphic",                                        // Property name
          typeof(Uri),                                              // Property type
          typeof(SilverlightControl1),                              // Type of the dependency property provider
          new PropertyMetadata(null,                                // 默认的值
              new PropertyChangedCallback(OnUriChanged)               // Callback invoked on property value has changes
          )
        );

        /// <summary>
        /// Create the property and use the SetValue/GetValue methods of the DependencyObject class
        /// </summary>
        public Uri AquariumGraphic
        {
            get { return (Uri)GetValue(AquariumGraphicProperty); }
            set { SetValue(AquariumGraphicProperty, value); }
        }
             
        public SilverlightControl1()
        {
            InitializeComponent();
        }        
     
        /// <summary>
        /// 值变化时,更新显示
         /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        private static void OnUriChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Shape sh = (Shape)d;
            ImageBrush ib = new ImageBrush();
            ib.ImageSource = new BitmapImage(e.NewValue as Uri);
            sh.Fill = ib;
        }

     
    }
}

我们首先来看看 AquariumGraphicProperty ,类型就是DependencyProperty,前面用了static readonly,一个单例模式,有DependencyProperty.Register,看起来像是往容器里注册,其实也差不多。

再来看AquariumGraphic,和传统的属性没什么区别,类型是 Uri 型,有get,set方法。只不过内部的实现分别调用了GetValue和SetValue,这两个方法是DependecyObject(简称DO,是WPF/Silverlight中所有可视Visual的基类)暴露出来的,传入的参数是AquariumGraphicProperty。

需要注意的是运行时,Xaml中是直接调用GetValue和SetValue的。所以,为了让使用XAML设置属性与使用代码设置属性一致,在属性包装器中除了GetValue和SetValue调用以外,不应该包含任何其他逻辑,这是非常重要的。如果需要添加自定义逻辑,应该在Register的回调函数中添加。

 

参考资料:

.Net3.0里的DependencyProperty(1):引入了DP的一些基本概念
http://www.cnblogs.com/yayx/archive/2007/05/26/761117.html

WPF里的DependencyProperty(2):DP的应用,主要想解释我们为什么要用它
http://www.cnblogs.com/yayx/archive/2008/04/20/1162963.html

WPF里的DependencyProperty(3):主要想演示下怎么用DP
http://www.cnblogs.com/yayx/archive/2008/04/22/1166064.html

WPF/Silverlight为什么要使用Canvas.SetLeft()这样的方法? :附属,从布局应用上解释了下为什么要有AttachedProperty
http://www.cnblogs.com/yayx/archive/2008/04/23/1167110.html

WPF里的DependencyProperty(4):介绍了DP的工作机制
http://www.cnblogs.com/yayx/archive/2008/04/24/1168738.html

WPF里的DependencyProperty(5) :介绍了PropertyMetadata和AttachedProperty
http://www.cnblogs.com/yayx/archive/2008/06/03/1213126.html

Windows Presentation Foundation 体系结构
http://msdn.microsoft.com/en-us/ms750441(zh-cn).aspx

如何学好WPF
http://www.cnblogs.com/zhouyongh/archive/2009/07/31/1536000.html

Tip: How to declare a dependency property in Silverlight?
http://www.silverlightshow.net/tips/Tip-How-to-declare-a-dependancy-property-in-Silverlight.aspx

WPF体系结构-- System.Windows.DependencyObject与智能的控件
http://bbniu.com/forum/thread-478-1-1.html

图解DotNet框架之九:WPF
http://www.cnblogs.com/xugao918/archive/2008/08/01/1258193.html

Silverlight自定义依赖项对象和依赖项属性
http://msdn.microsoft.com/zh-cn/library/cc903933(VS.95).aspx

posted on 2010-02-07 16:35:41 by ghj1976  评论(0) 阅读(768)

SharePoint 2010中新增的GetItemByIdSelectedFields方法

唔……事先声明,其实这篇文章没有太多实际的使用意义,所以想了解某个东东怎么用的同学可以按Alt + F4(或者Ctrl + W)了。想了解SharePoint里面是怎么工作的同学可以继续往下翻。

最近正在和KB一起写关于SharePoint 2010开发方面的一本书,在研究2010新增加的对象模型的时候,偶然发现了这个方法。我们都知道在2003/2007里面,根据ID获取列表条目使用的是SPList的GetItemById方法(什么,没听说过这个方法?那恐怕你不是一个合格的SharePoint开发人员……)。新增加的这个方法名字叫GetItemByIdSelectedFields(同时也增加了一个GetItemByIdAllFields的方法与之作伴,不过这个和GetItemById是完全等效的,就不再废话了),方法的定义是这样的:

   1: public SPListItem GetItemByIdSelectedFields(int id, params string[] fields)

当我第一眼看到这个的时候,立刻就想到了SPQuery的那个ViewFields属性,获取某个列表条目的时候,只返回某些指定的字段,来提高效率。可是当我写了个Console程序试验的时候,发现并不是我想象中的样子,比如我写成(这个方法要求写内部名称):

   1: SPListItem item = spList.GetItemByIdSelectedFields(1, "Title", "Created");
   2: Console.WriteLine(item["Modified"]);

这段程序居然没有报错,而且Modified的值也正常返回了,于是我试了试,一个自定义列表里面居然有50来个字段的值都正常返回了,但是所有的查阅项、用户和用户组(其实这个本质上也是查阅项)都没有返回。

在好奇驱使下(暂时还害不死我),我Reflector了一下这个方法的源代码:

   1: if(field == null)
   2: {
   3:   throw new ArgumentNullException("fields");
   4: }
   5:  
   6: StringBuilder builder = new StringBuilder();
   7: foreach (string str in fields)
   8: {
   9:   if (str != null)
  10:   {
  11:     builder.Append("<FieldRef Name=\"" + str + "\"/>");
  12:   }
  13: }
  14:  
  15: foreach (SPField field in this.Fields)
  16: {
  17:   bool flag = false;
  18:   foreach (string str2 in fields)
  19:   {
  20:     if (str2 == field.InternalName)
  21:     {
  22:       flag = true;
  23:       break;
  24:     }
  25:   }
  26:   if (!flag && field.MustFetchByDefault)
  27:   {
  28:     builder.Append("<FieldRef Name=\"");
  29:     builder.Append(field.InternalName);
  30:     builder.Append("\"/>");
  31:   }
  32: }
  33:  
  34: return this.GetItemById(id, null, false, builder.ToString());

关于最后那个GetItemById是怎么回事,暂时先不用再去深究了,只要知道它是一个GetItemById的重载,目的就是查找条目用的就行了,最后一个参数把需要获取的字段以CAML的形式放进去。

第7行那个foreach很好理解,把我们需要的字段加进去;但是第15行的那个foreach一开始就有点让人摸不着头脑了,还要把其他字段也放进去?而且SPField的这个MustFetchByDefault是什么东西?再挖挖看看:

   1: internal bool MustFetchByDefault
   2: {
   3:   get
   4:   {
   5:     string fieldAttributeValue = this.GetFieldAttributeValue("List");
   6:     if(!string.IsNullOrEmpty(fieldAttributeValue) &&
   7:        (fieldAttrbuteValue != GlobalList.Docs.ToString()))
   8:     {
   9:       return false;
  10:     }
  11:     return true;
  12:   }
  13: }

如何判断一个字段是不是要取呢?通过判断字段的一个List属性,至于GetFieldAttributeValue方法就不再往上贴了(否则有骗字数的嫌疑),总之它是从Field的类似SchemaXml属性(字段描述)的Xml结点中,去找一个List的属性。如果找到了,而且不是GlobalList.Docs(某个特殊的东东)的话,那么这个字段就不是必须的,换句话说这个字段我就不用返回给用户。

那什么字段的SchemaXml里会有List属性?一个字段里有一个和列表的属性?查阅项!哈,真的是回避掉了所有的查阅项。(Docs这个东西是“路径”这个字段的List属性,估计有某些特殊的来源)

现在我们知道为什么会包含其他所有字段,并且不包含查阅项了。但是为什么要这样?如果我们对SharePoint的内容数据库有所了解的话,我们会知道其实查阅项在内容数据库里只存了一个ID值在AllUserData表里面(但是用对象模型取出来的时候,是包含查阅那个条目相应字段的内容的),这也就意味着,如果要返回查阅项的值,就需要多做一些额外的数据库操作(比如再去找到被查阅的那个条目,把相应字段的值返回来,拼装成“1;#Administrator“这种鬼样子)。更重要的是,如果这个查阅项是一个多值的,那么这个查阅项本身都是保存在另外一个表中的(AllUserDataJunctions),这样要返回起来还真是要费不少功夫。所以2010里面新增加了这么一个东西,如果我们的列表中包含好多个查阅项,而我们可能暂时只用到其中一两个(或者一个都不用)的话,看来用这个方法确实能提高不少效率。

posted on 2010-02-03 00:12:19 by erucy  评论(0) 阅读(1107)

SQL IP to BigInt

前一篇博客 IP to Integer 提供的 SQL 函数是 IP 转换成 Integer 的方法。 Integer 的最大值为: 2147483647(2^31 - 1)。按照 IP 转换成整数的算法,会算出来大于这个值的,所以之前提供的 IP 转换成 Integer 的方法会算出负值。

下面是 IP to BigInt 的转换算法, 这时候运算就不会小于零。

CREATE FUNCTION dbo.ipStringToBigInt 
( 
    @ip CHAR(15) 
) 
RETURNS bigint 
AS 
BEGIN 
    DECLARE @rv bigint, 
        @o1 bigint, 
        @o2 INT, 
        @o3 INT, 
        @o4 INT
 
    SELECT 
        @o1 = CONVERT(INT, PARSENAME(@ip, 4)), 
        @o2 = CONVERT(INT, PARSENAME(@ip, 3)), 
        @o3 = CONVERT(INT, PARSENAME(@ip, 2)), 
        @o4 = CONVERT(INT, PARSENAME(@ip, 1)) 
 
    IF (@o1 BETWEEN 0 AND 255) 
        AND (@o2 BETWEEN 0 AND 255) 
        AND (@o3 BETWEEN 0 AND 255) 
        AND (@o4 BETWEEN 0 AND 255) 
    BEGIN      
 
        SET @rv = (@o1 * 16777216)  +  
            (@o2 * 65536) +  
            (@o3 * 256) + 
            (@o4) 
    END 
    ELSE 
        SET @rv = -1 
    RETURN @rv 
END
go 



CREATE FUNCTION dbo.ipBigIntToString 
( 
    @ip bigint 
) 
RETURNS CHAR(15) 
AS 
BEGIN 
    DECLARE @o1 INT, 
        @o2 INT, 
        @o3 INT, 
        @o4 INT 
 
    IF @ip > 4294967295 RETURN '255.255.255.255' 
    IF @ip <= 0 RETURN '0.0.0.0' 
 
    SET @o1 = @ip / 16777216
 
    SET @ip = @ip % 16777216 
    SET @o2 = @ip / 65536 
    SET @ip = @ip % 65536 
    SET @o3 = @ip / 256 
    SET @ip = @ip % 256 
    SET @o4 = @ip 
 
    RETURN 
        CONVERT(VARCHAR(4), @o1) + '.' + 
        CONVERT(VARCHAR(4), @o2) + '.' + 
        CONVERT(VARCHAR(4), @o3) + '.' + 
        CONVERT(VARCHAR(4), @o4) 
END

go 

-- 调用例子
select dbo.ipBigIntToString(3708279131)
select dbo.ipStringToBigInt('221.7.217.91')

posted on 2010-02-02 11:22:53 by ghj1976  评论(0) 阅读(1294)

MatrixTransform

MatrixTransform 通过创建一个任意仿射矩阵变换,用于操作二维平面中的对象或坐标系。由于仿射变换时,平行的边依然平行,所以,我们无法对一个矩形的位图进行随意变换,比如我们无法拉伸一个角,也无法进行把它变成梯形等。如下图所示:就类似光线照射下,图形的投影。

01000000000000119081530541941

如下图,从矩形是无法转换成后一种的。

t_affine

旋转、倾斜、平移、缩放 是最常用的仿射变换,对应就是RotateTransform、SkewTransform、TranslateTransform、ScaleTransform 类。

有关这四种变化可以参看我之前写的博客:

Silverlight学习笔记--通用绘图属性
http://blog.joycode.com/ghj/archive/2009/11/30/115793.joy

Silverlight 图形的转换
http://blog.joycode.com/ghj/archive/2010/01/05/115841.joy

由于 MatrixTransform之相关矩阵运算 可以看下面我写的博客:
http://blog.joycode.com/ghj/archive/2010/01/28/115865.joy 

 

MatrixTransform主要通过点的矩阵变换来实现图形的改变,我们常看到的一些效果,如对称效果,就可以通过矩阵变换来实现。

首先,我们先来了解一下MatrixTransform的所有参数的意义,MatrixTransform的参数如下:{M11, M 12, M 21, M22, OffesetX,OffsetY}

其中:{ M11, M12, M21, M22}构成一个矩阵A,用于坐标的变换,{ OffesetX,OffsetY }构成平移向量O,用于坐标的平移。

 

据我在Google上搜索,使用 MatrixTransform 并没有提供更多的 仿射变换 功能,我们使用 MatrixTransform 来创建 自定义变换也就是旋转、倾斜、平移、缩放这几种的组合。

 

下面是一个演示,我们可以手工修改 M11, M 12, M 21, M22, OffesetX,OffsetY ,继而可以看到矩形的变化效果,在输入框上滚动鼠标中轮也可以增加或者减少数字。

 

演示程序的代码:

Xaml 文件

<UserControl x:Class="SilverlightApp_MatrixTransform.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="200" d:DesignWidth="400" >

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200"/>
            <ColumnDefinition Width="50"/>
            <ColumnDefinition Width="50"/>
            <ColumnDefinition Width="50"/>
            <ColumnDefinition Width="50"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="0.33*"/>
            <RowDefinition Height="0.34*"/>
            <RowDefinition Height="0.33*"/>
        </Grid.RowDefinitions>
        <Rectangle Fill="#FF186ED0" Stroke="Black" Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" x:Name="rectangle" 
                   Width="100" Height="100" VerticalAlignment="Center" HorizontalAlignment="Center">
            <Rectangle.RenderTransform>
                <MatrixTransform x:Name="rectangleMatrix">
                </MatrixTransform>
            </Rectangle.RenderTransform>
        </Rectangle>
        <TextBlock Grid.Column="1" Grid.Row="0"  Text="M11:" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        <TextBox x:Name="tb_M11"  Text="1.0" VerticalAlignment="Center" TextAlignment="Center" 
                 Grid.Row="0" Grid.Column="2" d:LayoutOverrides="Width" />
        <TextBlock Grid.Column="3" Grid.Row="0"  Text="M12:" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        <TextBox x:Name="tb_M12"  Text="0.0" VerticalAlignment="Center" TextAlignment="Center"
                 Grid.Row="0" Grid.Column="4" d:LayoutOverrides="Width" />

        <TextBlock Grid.Column="1" Grid.Row="1"  Text="M21:" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        <TextBox x:Name="tb_M21"  Text="0.0" VerticalAlignment="Center" TextAlignment="Center" 
                 Grid.Row="1" Grid.Column="2" d:LayoutOverrides="Width" />
        <TextBlock Grid.Column="3" Grid.Row="1"  Text="M22:" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        <TextBox x:Name="tb_M22"  Text="1.0" VerticalAlignment="Center" TextAlignment="Center" 
                 Grid.Row="1" Grid.Column="4" d:LayoutOverrides="Width" />

        <TextBlock Grid.Column="1" Grid.Row="2"  Text="offsetX:" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        <TextBox x:Name="tb_offsetX"  Text="0.0" VerticalAlignment="Center" TextAlignment="Center" 
                 Grid.Row="2" Grid.Column="2" d:LayoutOverrides="Width" />
        <TextBlock Grid.Column="3" Grid.Row="2"  Text="offsetY:" VerticalAlignment="Center" HorizontalAlignment="Center"/>
        <TextBox x:Name="tb_offsetY"  Text="0.0" VerticalAlignment="Center" TextAlignment="Center" 
                 Grid.Row="2" Grid.Column="4" d:LayoutOverrides="Width" />

    </Grid>
</UserControl>

C# 文件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightApp_MatrixTransform
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        Matrix m = new Matrix();

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            this.tb_M11.MouseWheel += new MouseWheelEventHandler(TextBox_MouseWheel);
            this.tb_M11.GotFocus += new RoutedEventHandler(TextBox_GotFocus);
            this.tb_M11.TextChanged += new TextChangedEventHandler(TextBox_TextChanged);
            this.tb_M12.MouseWheel += new MouseWheelEventHandler(TextBox_MouseWheel);
            this.tb_M12.GotFocus += new RoutedEventHandler(TextBox_GotFocus);
            this.tb_M12.TextChanged += new TextChangedEventHandler(TextBox_TextChanged);
            this.tb_M21.MouseWheel += new MouseWheelEventHandler(TextBox_MouseWheel);
            this.tb_M21.GotFocus += new RoutedEventHandler(TextBox_GotFocus);
            this.tb_M21.TextChanged += new TextChangedEventHandler(TextBox_TextChanged);
            this.tb_M22.MouseWheel += new MouseWheelEventHandler(TextBox_MouseWheel);
            this.tb_M22.GotFocus += new RoutedEventHandler(TextBox_GotFocus);
            this.tb_M22.TextChanged += new TextChangedEventHandler(TextBox_TextChanged);
            this.tb_offsetX.MouseWheel += new MouseWheelEventHandler(TextBox_MouseWheel);
            this.tb_offsetX.GotFocus += new RoutedEventHandler(TextBox_GotFocus);
            this.tb_offsetX.TextChanged += new TextChangedEventHandler(TextBox_TextChanged);
            this.tb_offsetY.MouseWheel += new MouseWheelEventHandler(TextBox_MouseWheel);
            this.tb_offsetY.GotFocus += new RoutedEventHandler(TextBox_GotFocus);
            this.tb_offsetY.TextChanged += new TextChangedEventHandler(TextBox_TextChanged);
        }

        private void TextBox_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            TextBox tb = sender as TextBox;
            if (tb == null) return;
            double w = 1.0;
            if (double.TryParse(tb.Text, out w))
                w = w + (double)e.Delta / 100;
            else
                w = 1.0;
            if (tb != null)
                tb.Text = w.ToString();
        }

        private void TextBox_GotFocus(object sender, RoutedEventArgs e)
        {
            TextBox box = sender as TextBox;
            box.Select(0, box.Text.Length);
        }

        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            TextBox tb = sender as TextBox;
            if (tb == null) return;

            double w = 1.0;
            if (!double.TryParse(tb.Text, out w)) w = 1.0;

            switch (tb.Name)
            {
                case "tb_M11":
                    m.M11 = w;
                    break;
                case "tb_M12":
                    m.M12 = w;
                    break;
                case "tb_M21":
                    m.M21 = w;
                    break;
                case "tb_M22":
                    m.M22 = w;
                    break;
                case "tb_offsetX":
                    m.OffsetX = w;
                    break;
                case "tb_offsetY":
                    m.OffsetY = w;
                    break;
                default:
                    break;
            }
            rectangleMatrix.Matrix = m;
        }
    }
}

参考资料:

WPF中的MatrixTransform
http://www.cnblogs.com/zhouyinhui/archive/2007/07/07/809553.html

稳扎稳打Silverlight(10) - 2.0其它之Transform详解,以及UIElement和FrameworkElement的常用属性
http://www.cnblogs.com/webabcd/archive/2008/11/03/1325150.html

MatrixTransform 类
http://msdn.microsoft.com/zh-cn/library/system.windows.media.matrixtransform.aspx

Basic Understanding of Matrix Transformation
http://blogs.msdn.com/joseph_fultz/archive/2009/07/31/basic-understanding-of-matrix-transformation.aspx

Silverlight Terrain Tutorial Part 2 – Using Transform Matrices to Create 3D Looking Terrain.
http://blogs.silverlight.net/blogs/msnow/archive/2008/08/18/terrain-tutorial-part-2-using-transform-matrices-to-create-3d-looking-terrain.aspx

MatrixTransform
http://blogs.msdn.com/jstegman/archive/2006/04/02/566939.aspx

WPF中MatrixTransform的理解与应用
http://blog.csdn.net/artlife/archive/2007/01/08/1477360.aspx

二维几何图形变换及其GDI+实现
http://www.cnblogs.com/begincsdn/archive/2005/07/14/193005.html

Silverlight Transforms
http://msdn.microsoft.com/en-us/library/cc189037(VS.95).aspx

Understanding the Transformation Matrix in Flash 8
http://www.senocular.com/flash/tutorials/transformmatrix/

Transformation Matrix in Silverlight 2
http://joel.neubeck.net/2008/09/transformation-matrix-in-silverlight-2/

AS3位图任意形变一步一步来(2)——计算变换矩阵
http://fdream.net/blog/article/632.aspx

posted on 2010-02-01 14:56:44 by ghj1976  评论(0) 阅读(1274)

IP to Integer

有时候我们要判断某个IP是否在某个段内,如何实现呢? 一个简单办法就是把IP转换成Integer,然后判断整数是否在某个范围内就可以实现这个判断。

转换的算法如下:

比如我们要转换的IP为: 058.062.042.000

First Octet: 058
Second Octet: 062
Third Octet: 042
Fourth Octet: 000

计算公式如下:
(first octet * 256³) + (second octet * 256²) + (third octet * 256) + (fourth octet)
=  (first octet * 16777216) + (second octet * 65536) + (third octet * 256) + (fourth octet)
=  (058 * 16777216) + (062 * 65536) + (042 * 256) + (000)
=  977152512

网上有现成的服务,比如下面这个地址:

http://www.aboutmyip.com/AboutMyXApp/IP2Integer.jsp

SQL Server 的一个例子如下:

CREATE FUNCTION dbo.ipStringToInt 
( 
    @ip CHAR(15) 
) 
RETURNS INT 
AS 
BEGIN 
    DECLARE @rv INT, 
        @o1 INT, 
        @o2 INT, 
        @o3 INT, 
        @o4 INT, 
        @base INT 
 
    SELECT 
        @o1 = CONVERT(INT, PARSENAME(@ip, 4)), 
        @o2 = CONVERT(INT, PARSENAME(@ip, 3)), 
        @o3 = CONVERT(INT, PARSENAME(@ip, 2)), 
        @o4 = CONVERT(INT, PARSENAME(@ip, 1)) 
 
    IF (@o1 BETWEEN 0 AND 255) 
        AND (@o2 BETWEEN 0 AND 255) 
        AND (@o3 BETWEEN 0 AND 255) 
        AND (@o4 BETWEEN 0 AND 255) 
    BEGIN      
        SELECT @base = CASE 
            WHEN @o1 < 128 THEN 
                (@o1 * 16777216) 
            ELSE 
                -(256 - @o1) * 16777216 
            END 
     
        SET @rv = @base +  
            (@o2 * 65536) +  
            (@o3 * 256) + 
            (@o4) 
    END 
    ELSE 
        SET @rv = -1 
    RETURN @rv 
END
go

调用范例:

select dbo.ipStringToInt('058.062.042.000')

整数转换如下:

CREATE FUNCTION dbo.ipIntToString 
( 
    @ip INT 
) 
RETURNS CHAR(15) 
AS 
BEGIN 
    DECLARE @o1 INT, 
        @o2 INT, 
        @o3 INT, 
        @o4 INT 
 
    IF ABS(@ip) > 2147483647 
        RETURN '255.255.255.255' 
 
    SET @o1 = @ip / 16777216 
 
    IF @o1 = 0 
        SELECT @o1 = 255, @ip = @ip + 16777216 
 
    ELSE IF @o1 < 0 
    BEGIN 
        IF @ip % 16777216 = 0 
            SET @o1 = @o1 + 256 
        ELSE 
        BEGIN 
            SET @o1 = @o1 + 255 
            IF @o1 = 128 
                SET @ip = @ip + 2147483648 
            ELSE 
                SET @ip = @ip + (16777216 * (256 - @o1)) 
        END 
    END 
    ELSE 
    BEGIN 
        SET @ip = @ip - (16777216 * @o1) 
    END 
 
    SET @ip = @ip % 16777216 
    SET @o2 = @ip / 65536 
    SET @ip = @ip % 65536 
    SET @o3 = @ip / 256 
    SET @ip = @ip % 256 
    SET @o4 = @ip 
 
    RETURN 
        CONVERT(VARCHAR(4), @o1) + '.' + 
        CONVERT(VARCHAR(4), @o2) + '.' + 
        CONVERT(VARCHAR(4), @o3) + '.' + 
        CONVERT(VARCHAR(4), @o4) 
END
go

调用范例:

select dbo.ipIntToString(977152512)

C# 的例子如下:

using System;
using System.Net;

namespace ConsoleApplication1
{
    class Program
    {
        static long ToInt(string addr)
        {
            return BitConverter.ToInt32(IPAddress.Parse(addr).GetAddressBytes(), 0); 
        }

        static string ToAddr(long address)
        {
            return IPAddress.Parse(address.ToString()).ToString();
            // This also works: 
            // return new IPAddress((uint) IPAddress.HostToNetworkOrder( 
            //    (int) address)).ToString(); 
        }

        static void Main(string[] args)
        {
            Console.WriteLine(ToInt("64.233.187.99"));
            Console.WriteLine(ToAddr(1089059683)); 

            Console.ReadLine();
        }
    }
}

参考资料:

How should I store an IP address in SQL Server?
http://sqlserver2000.databases.aspfaq.com/how-should-i-store-an-ip-address-in-sql-server.html

How to convert an IPv4 address into a integer in C#?
http://stackoverflow.com/questions/461742/how-to-convert-an-ipv4-address-into-a-integer-in-c

posted on 2010-01-28 15:04:44 by ghj1976  评论(3) 阅读(1858)

MatrixTransform之相关矩阵运算

最近在学习MatrixTransform,发现对之前学的矩阵乘法竟然忘的一干二净,下面就是这个基础知识的整理。

 

矩阵加法

通常的矩阵加法被定义在两个相同大小的矩阵。两个m×n矩阵A和B的和,标记为A+B,一样是个m×n矩阵,其内的各元素为其相对应元素相加后的值。例如:

973b1461ec9b7c49a781e39aa22623c2

也可以做矩阵的减法,只要其大小相同的话。A-B内的各元素为其相对应元素相减后的值,且此矩阵会和A、B有相同大小。例如:

8e411287f504ba4fe4b6a9a93d2a4f03

 

矩阵乘法

若给出一矩阵 A 及一数字 c,可定义标量积 cA,其中 (cA)[i, j] = cA[i, j]。 例如:

8951d4762a38dcb7a372bb6a5ee0d623

 

设A和B是两个给定如下的矩阵:

95d86d25f324076227a08a1de8ffebbb  b692829bf4f96dbcadb20d1de06aa8a6

8dd1d643ed85e951c415a39cf690b659

举例来说: 

7b62cda9a2e78e8414806c5aea486b5c d3c223ed4af4939e565893b2f3136bae

MatrixTransform  的矩阵运算

假设我们有个点(X,Y) ,我们使用 MatrixTransform  要把它转换成新的点(X1,Y1),则公式为:

X1 = X*M11 + Y*M21+ OffsetX
Y1 = X*M12 + Y*M22+ OffsetY

在Silverlight 和 WPF 中,对应的Xaml 如下:

<MatrixTransform Matrix="M11, M12, M21, M22, OffsetX, OffsetY"/> 

从矩阵运算的角度,就是如下矩阵运算:

image

上述表达式中,乘号左面矩阵的列为为系数表,右边矩阵为向量表。例如,第一行是[X Y 1],因此将X乘上第一个向量,Y乘上第二个向量,1则乘上第三个向量。

参考资料:

矩阵
http://zh.wikipedia.org/zh-cn/%E7%9F%A9%E9%98%B5

矩阵加法
http://zh.wikipedia.org/zh-cn/%E7%9F%A9%E9%99%A3%E5%8A%A0%E6%B3%95

矩阵乘法
http://zh.wikipedia.org/zh-cn/%E7%9F%A9%E9%99%A3%E4%B9%98%E6%B3%95

3D 图形编程的数学基础(2) 矩阵及其运算
http://blog.csdn.net/vagrxie/archive/2009/12/09/4974985.aspx

WPF中的MatrixTransform
http://www.cnblogs.com/zhouyinhui/archive/2007/07/07/809553.html

MatrixTransform
http://blogs.msdn.com/jstegman/archive/2006/04/02/566939.aspx

SVG 的矢量运算
http://www.w3.org/TR/SVG11/coords.html#TransformMatrixDefined

posted on 2010-01-28 10:00:08 by ghj1976  评论(0) 阅读(1599)

【第1页/共736页,7360条】
首页
前页
1
...