使用数据服务, 将Outlook预约整合到SharePoint 2010 日历列表中

[原文作者]:Beth Massi

[原文链接]:Integrate Outlook Appointments with SharePoint 2010 Calendar Lists using Data Services

        一天, 我的一个朋友问我有没有可能发送一个在Outlook里创建的预约到SharePoint日历列表中. 这样的话, 我们通过使用Visual Studio 构建一个外接程序, 就变的非常简单的获取这些Outlook的数据. 我们知道, 使用内建的WCF数据服务发送消息到SharePoint是一件很容易的事情. 下面我就与你分享一下更新这些数据通过WCF服务.

创建Outlook外接程序和添加Sharepoint数据服务引用

        我打算使用Visual Studio 2010创建一个Outlook 2010外接程序, 当然你也可以创建一个OutLook 2007 外接程序, 事实上, 你也可以使用Visual Studio 2008 来创建OutLook外接程序和访问数据服务, 你只需要保证你使用的是.Net 3.5或更高的版本.

        文件->新建->项目, 选择Office 2010节点, 再选择OutLook 2010 外接程序. 我把这个事例命名为UpdateSharePointCalendar, 接下来我们要做的第一件事情是添加一个SharePoint 2010 数据服务引用到我们刚才新建的项目, 当然你也可以使用相同的方法添加一些其他的WCF数据服务. 在项目上单击右键, 选择添加服务引用, 如果你已经安装了SharePoint 2010, 你就可以通过向导的方式找到你想要的数据服务, 你可以通过这种方式http://<servername>/_vti_bin/ListData.svc来访问这些数据服务. 在我的本地的机器上已经安装了SharePoint 2010, 所有我使用这个地址: http://localhost/_vti_bin/ListData.svc并且把这个数据服务命名为 SPService.

        一旦我们添加了这个服务引用, 客户端的实体类型将会自动生成, 并且这个程序集引用System.Data.Services.Client 也已经添加了. 所有的SharePoint 的服务, 方法和数据已经可以被客户端所调用. 我们可以打开数据协议展台来浏览这些数据类型. 只要你安装了数据协议展台, 你在数据服务SPService上单击右键然后选择”查看用图表的方式”, 展开实体类型, 然后把CalendarItem 拖到图表中查看他的属性, 你可以看到有很多字段是SharePoint私有的, 当然你也可以看到如Title, StartTime, EndTime 和Description是我们可以外部调用的.

image

添加窗体 Region Ribbon Outlook预约

        现在我们已经添加了一些数据服务引用和一些界面元素, 对于这个例子, 我想显示一个并列的窗体当用户创建一个新的Outlook预约时, 并且所有的事件必须显示在SharePoint的日历中在那天. 我将使用一个简单的只读的Data Grid 在这个例子中, 但是它可以显示所有的东西在这里(尽管在过去我喜欢使用WPF控件), 当然我还需要添加一个按钮到Ribbon以至于用户可以单击它来发送预约信息到SharePoint日历列表.

        我们在项目上单击右键选择添加-> 新建元素然后选择OutLook窗体Region, 我把它命名为AddToSharePoint, 单击添加, 下一步选择”设计一个新的窗体Region”, 下一步选择窗体Region的类型, 在这里, 对于并行的窗体, 我觉得把它命名为” SharePoint Calendar Events”.

        在这个界面的底部,要求我们选择窗体区域的显示模式, 默认是三种模式都被选中, 如果我们添加这个窗体区域到邮件上, 这个区域应该需要显示, 因此, 只读面板, 分离组建和只读模式对于OutLook的预约来说是不需要的, 我们需要的是检测用户有没有创建一个新的预约在运行时. 点击下一步, 然后选择预约消息的类, 这个类将会关联到窗体区域, 最后点击完成按钮.

image

        这个窗体区域仅仅是一个用户控件并且在这个例子中我们仅仅使用data grid来显示数据, 所有我想打开数据资源窗口(数据->显示数据资源)并且把Calendar拖到用户控件中, 这会为我们创建一个CalendarBindingSource并且会自动添加相应的数据绑定, 我们需要做的事情是设置CalendarBindingSource.DataSource的属性在代码中以至于我们的数据在Grid中可以显示. 接下来我们编辑我们想显示的列并且设置data grid 为只读属性.

image

       现在我想添加一个Ribbon, 在项目上右键选择添加->新建项, 然后选择Ribbon并且单击添加按钮. 第一件我们要做的事情是把Ribbon关联到Outlook的预约, 我们要做的就是把Ribbon的属于RibbonType 设置为Microsoft.Outlook.App

image

        通过上面的设置, 这个Ribbon按钮就应该会出现在我们新建的预约的第一个选项卡中, 为了做到这一点, 我们还需要了就OutLook的内部控制标识符, 在这个例子中, 你可以找到它在这个OutlookAppointmentItemControls.xlsx, 这里你也可以看到一个名字为TabAppointment 的主选项卡, 所有在我们Ribbon的设计器中选择选项卡然后在属性中设置ControlID 为TabAppointment.最后我们再从工具箱拖一个按钮到Group1命名为BtnSharePoint并且设置它的ControlSize 属性为Large. 这里我们还可以创建自己的照片, 但是我很懒, 所有我就用OutLook中已经存在的一个非常漂亮的图片作为我的照片. 内建图片的IDs是很容易找到的, 如果你用的是OutLook”自定义的Ribbon”, 你也可以从文件->选项中找到. 你只需要停留在你喜欢的照片上面, 在括号中你就会看到你要的IDs. 然后在”Ribbon”按钮的

对拷贝不安全的类型 禁止拷贝构造函数

[原文作者]:Jared Parsons

[原文链接]:Disable copy construction when the type is not copy safe

        几天前,我用C++代码来实现一个功能,点击F5弹出令人讨厌的内存破坏调试窗口。在将近一个小时的调查之后,我发现有一个类型在堆栈的生命周期之外仍然存在。我决定接下来要在堆函数里调试来看哪里出错了。我打开了那个堆栈的文件,而几乎是同时也知道了出错的地方。

下面是我看的那个堆文件的简化版本:

class SpecialHeap {

public:

SpecialHeap() {

m_pBlock = ::VirtualAlloc(…);

// Memory management magic

}

~SpecialHeap() {

VirtualFree(m_pBlock, …);

}

void* Allocate(sizet_ bytes) { }

private:

void* m_pBlock;

}

        有没有人现在已经知道哪里出错了?

        相关的是那些没出现在屏幕上的代码。也就是默认的由C++编译器生成的拷贝构造函数。在C++中,编译器会给那些不明确定义拷贝构造函数的类型一个默认拷贝构造函数。这对C++好多类型都是很棒的,因为它支持很方便的拷贝,而不需要用户额外的代码。

        然而对一种类型是很麻烦的,这种类型管理那些不被共享的资源。例如我们例子中的SpecialHeap.通过拷贝构造函数创建的SpecialHeap的任何实例都是一个定时炸弹。一个拷贝意味着有一个源,因此2个SpecialHeap的实例运行最后都指向相同的m_pBlock. 第一个析构函数运行之后,另一个实例就只有一个垃圾指针了。

        看了这个之后,我几乎肯定我在SpecialHeap的参数里遗忘了一个&,我准备用引用传递的。相反,我创建了一个拷贝,这时,当方法返回时破坏了堆空间。快速看一遍我的修改,这确实是个问题。

        令人沮丧的是这个问题100%可以避免。通过简单声明一个用户定义的拷贝构造函数,而不实现它,类型可以选择退出。

private:

// Disable value copying

SpecialHeap(const SpecialHeap&);

SpecialHeap& operator=(const SpecialHeap&);

        这几行代码只是把我的运行时错误转变成了一个编译错误。对于这个问题,让人沮丧的是,它花了不到一分钟的时间去定义,却可以节省我1个小时的调试时间,这种类型并不是安全拷贝,并且允许它有一个拷贝构造函数本身就是一个错误。

        这种方式对这个错误来说并不特殊。在C++中,对任何一个定义单一的类型,如果没有明确拷贝的意图,都要做这件事。养成添在这种地方加以上代码的习惯会为你和他人节约几个小时的调试时间。

Windows Phone 7 背景布局设计应用举例

[原文链接]:Sample: Windows Phone 7 Example Application with Landscape Layout

[原文作者]:Jason Zanders

        我已经写了很多关于Windows Phone 7的应用,在这篇博客中我想说一下应该注意的地方并且共享示例的源代码以便于帮助你。Windows Phone 7最后的版本除了免费的Express SKU还支持Visual Studio 2010 。你可以在这里找到在开发过程中需要的所有东西。

        我最喜欢的手机应用之一就是计算器,它可以很容易计算出你在餐馆或者计程车的账单。用一个简单的例子说明这个计算器:

image

这个应用有一个内置的录入账单和控件,允许调整百分比和计算出总数。

布局

        Visual Studio可以很容易的创建一个包括风格和’Metro’为主题相匹配的应用,如Design and Interaction Guide的解释。该应用被分为三个网格:

image

每一个网格都会放置在相对应的行里使用Grid.Row 属性。

景观模式

        当用户旋转手机,我们需要改变布局匹配新的尺寸。这也是非常直截了当的去完成。第一步是在LayoutRoot里面有一个附加的列来容纳Total数据。

image

        当手机被旋转到景观模式,我们将会移动TotalsGrid 到紧挨NumberGrid的第二列。完成这项工作有几个步骤。首先LayoutRoot必需有3行和2列来放置显示的内容。

   1: <Grid x:Name="LayoutRoot" Background="{StaticResource PhoneBackgroundBrush}">
   2:     <Grid.RowDefinitions>
   3:         <RowDefinition Height="Auto"/>
   4:         <RowDefinition Height="Auto"/>
   5:         <RowDefinition Height="*"/>
   6:     </Grid.RowDefinitions>
   7:     <Grid.ColumnDefinitions>
   8:         <ColumnDefinition Width="Auto" />
   9:         <ColumnDefinition Width="0" x:Name="LandscapeColumn" />
  10:     </Grid.ColumnDefinitions>

        前面的两个RowDefinition元素将Height设置为’Auto’,这意味着它们消耗了所包含内容的空间。最后一行采取开放空间。第一列也设置Width为’Auto’。第二列’LandscapeColumn’的Width设为0,并且不会在肖像模式中使用。每一个网格默认的放置在自己的行。

        为了支持景观模式和肖像模式,这个应用必需声明支持设置和在事件中处理改变方向:

   1: SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;
   2:  
   3: this.OrientationChanged += new EventHandler<OrientationChangedEventArgs>(MainPage_OrientationChanged);

当方向改变,我们将会移动RotalsGrid到紧挨NumbersGrid的第二列,然后相应的改变列宽属性。

   1: void MainPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
   2: {
   3:     // In landscape mode, the totals grid is moved to the right on the screen
   4:     // which puts it in row 1, column 1.
   5:     if ((e.Orientation & PageOrientation.Landscape) != 0)
   6:     {
   7:         LandscapeColumn.Width = GridLength.Auto;
   8:         Grid.SetRow(TotalsGrid, 1);
   9:         Grid.SetColumn(TotalsGrid, 1);
  10:  
  11:         LayoutRoot.ColumnDefinitions[1].Width = GridLength.Auto;
  12:     }
  13:     // In portrait mode, the totals grid goes below the number pad at the
  14:     // bottom of the screen which is row 0, column 2.
  15:     else
  16:     {
  17:         LandscapeColumn.Width = new GridLength(0);
  18:         Grid.SetRow(TotalsGrid, 2);
  19:         Grid.SetColumn(TotalsGrid, 0);
  20:  
  21:         LayoutRoot.ColumnDefinitions[1].Width = new GridLength(0);
  22:     }
  23: }

最终显示的结果如下:

image

按钮处理

        数字键的按钮网格被创建成3 x4 xaml的格式。每一个按钮命名为’button[x]’对应它的值。当按下一个按钮的时候,我们想把这个数字加到账单里。我们可以用IDE手动增加一个句柄,但是通过利用C#匿名代理的功能可以做的更好。

   1: private void InitButtonHandlers()
   2: {
   3:     for (int i = 0; i <= 9; i++)
   4:     {
   5:         string btnName = "button" + i.ToString();
   6:         System.Windows.Controls.Button btn = 
   7:             (System.Windows.Controls.Button)this.LayoutRoot.FindName(btnName);
   8:  
   9:         int j = i; // avoid local variable capture
  10:         btn.Click += new RoutedEventHandler(
  11:             (object sender, RoutedEventArgs e) => { TryUpdateBillAmount(textBlockBill.Text + j.ToString()); }
  12:         );
  13:     }
  14: }

        这个循环通过名字找到每个按钮,然后增加新的Click handler。下面是最有趣的代码:

image

在循环中代码为每个按钮定义一个handler。 定义方法为带有参数列表的

RoutedEventHandler (object sender, RoutedEventArgs e)

The lambda syntax, =>, then leads us to the method implementation:

{ TryUpdateBillAmount(textBlockBill.Text + j.ToString()); }

在每一种情况下,代码利用当前视图的字符串值,追加新的数字,然后调用TryUpdateBillAmount方法,这个方法决定了更新是否有效。

这行代码非常有趣:

int j = i; // avoid local variable capture

当获取局部变量’i’时被认为是外部变量。这意味着’i’在堆上获取分配而不是堆栈,而且不会包含每个循环的值(如果在代理中使用’i’,你将总是获取到‘10’在这个例子中)。为了解决这个问题,我们在循环中生命了局部变量’j’来获取当前的值。(非常感谢和我一起设计C#语言规范的Scott Wiltamuth,是他帮我指出了这个问题!)

用仿真器调试

调试非常简单,仅仅是按下F5! 默认的选择以下的值:

image

当手机可用时,你也可以通过USB连接到电脑上,并且修改为以下的值:

image

你可以用Visual Studio 调试器和仿真控件来测试这个应用。比如:选择你想旋转的方向,测试景观模式。

image

总结

       你可以在这找到这个示例的全部代码,所用到的技术是通用的Silverlight和C#功能,证明了你的技术如何很容易的转化成新的形式,比如说手机。

Enjoy!

LightSwitch框架概述

[原文链接]:LightSwitch Architectural Overviews

[原文作者]:Jason Zanders

        上周我们发布了LightSwitch, 一个可以更简单编译商业应用程序的新开发工具. 感谢你们所有的建议和回答, 你们给了我们很多的反馈信息, 其中一个最主要的要求是提供更多关于利用LightSwitch编译应用程序的框架. 我们的团队一直在努力发布一些我正要分享给你们的资料, 其中包括深层次的框架技术:

image

希望以下链接能对你有所帮助:

我们将继续发布更多LightSwitch框架和技术信息, 同时也希望8月23号当发布补丁包时能有更多的文档信息.

用Visual Studio LightSwitch 快速开发商业应用程序

[原文作者] Bett Massi

[原文链接] Rapid Business Application Development with Visual Studio LightSwitch

        今天早上Jason Zander 宣布了一个激动人心的新产品——Visual Studio Light Switch的诞生,这是由微软的 VS Bizapps 团队打造的。

        终于能够谈谈这个产品了,对此我非常激动。能够在一个这样的团队里工作是一个很荣幸的事情, 每天能和这么多Visual Studio 工具打交道, 比如Office, Sharepoint 工具。但是在创建以数据为核心的商业应用程序的时候,LightSwitch显然是最贴心的一个。在加入微软之前的15年中,我曾经创建过各种各样的商业应用程序和应用程序框架,所以我非常开心我能加入我们的这个团队,做LightSwitch相关的工作。在从产品的Beta到发布阶段,我将会帮助写一些文章,帮助视频,和团队的访谈。

        LightSwitch使得对在桌面系统和云系统上创建以数据为核心的应用程序变得很简单。你能连接到不同的数据源(像SQL,Sharepoint, Azure, WCF Ria Service,等等),在坚实的.net架构上来创建功能丰富的Silverlight应用程序——你甚至不需要深入了解实体框架或Silverlight或多层设计。LightSwitch应用程序框架会为你处理这所有的事情。它还提供了很多商业应用程序框架之外的通用功能——比如一个完整的应用shell, 数据验证以及搜索。还有很多的屏幕和控件模板可供选择,以及全套的第三方附加控件,主题,模板,和插件, 这些我们都会通过VS库在LightSwitch的开发环境中实现。

        理念就是你只须专注于定义实体,屏幕,商业规则和流程。你只须编写与你的商业领域相关的你会写的代码。VB或C#皆可。

        我自己也是刚刚学会这些,但是我相信这会是一个很愉快的旅程。我非常高兴我接触到了它,而且也帮你们也学会了这么多。Beta1会于 8月23日在LightSwitch开发者中心发布。届时我们将会有更多的教程和演练。

        现在去看看我们今天上传的一些在线资源吧,等待我们的更多的消息。每周我们将会推出更多的视频在开发者中心上。

· LightSwitch开发者中心

· LightSwitch 团队博客

· LightSwitch Beta1论坛

        也可以听听来自今天的发布会的一些声音。

· LightSwitch简介

· LightSwitch:为Web,PC,Cloud创建商业应用程序

· LightSwitch:生产力的保证

· LightSwitch简介:快速开发LOB应用程序