2009年3月24日星期二

在SharePoint的Webpart中无法使用Resources

原因未明

使用ObjectDataSource重新查询

在使用ObjectDataSource作为数据源时,如果需要重新查询,则使用ObjectDataSource的Select方法即可。如下列代码:

protected void btnSearch_Click(object sender, EventArgs e)
{
this.CatalogDataSource.Select();
this.listCatalog.DataBind();
}

NHibernate在web.config中的配置

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<!-- SQL dialect -->
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<!--<property name="connection.connection_string1">Server=124.254.10.29,1436\sql2008;Initial Catalog=novi;User Id=novi;Password=L7JBwNq</property>-->
<property name="connection.connection_string">Server=devdc01;Initial Catalog=IBA_ECommerce_DB;User Id=ecomm;Password=iba+1234</property>
<!-- others -->
<property name="show_sql">true</property>
<!-- mapping files -->
<mapping assembly="IBA.ECommerce"/> 这个很重要,是所有映射类所在的DLL。
</session-factory>
</hibernate-configuration>

ListView中取得更改行的数据

在ListView中Update数据时,要取得所更新的数据信息。最好的方法是设置ListView的DataKeyNames。DataKeyNames即为绑定的数据对像的属性。比如这个Material的ID即为其Identify Field。那么,我们就可以在更新ListView时,取得所更新的DataKeyValue。

方法如下:

1. 设置ListView的DataKeyNames属性
<asp:ListView ID="listCatalog" runat="server" DataKeyNames="ID"
DataSourceID="CatalogDataSource" onitemupdated="listCatalog_ItemUpdated">
<LayoutTemplate>

2. 在ListView的OnItemUpdated事件中,
protected void listCatalog_ItemUpdated(object sender, ListViewUpdatedEventArgs e)
{
int i = listCatalog.EditIndex;
string reference = listCatalog.DataKeys[i].Value.ToString();
ShowMessagePanel(reference);
}


取得了修改行的ID值后,就可以使用Model的如Find或GetByID等得到修改的Class,进而修改数据。

ObjectDataSource和ListView的Update顺序

ListView的DataSourceID = CatalogDataSource

下而在更新时,事件的执行顺序:

protected void CatalogDataSource_Updated(object sender, ObjectDataSourceStatusEventArgs e)
{
// 1
}

protected void listCatalog_ItemUpdated(object sender, ListViewUpdatedEventArgs e)
{
// 2
}

2009年3月18日星期三

使用ListView + ObjectDataSource更新数据

这里面最关键的问题在于,当Update时,如何获取到修改行的TextBox的值。经探索,方法如下:
  1. 为ObjectDataSource指定UpdateMethod,并且设置UpdateParameters
  2. UpdateParameters只需要使用<Parameter即可
  3. 为ObjectDataSource创建OnUpdating事件
OnUpdating要做的工作如下:
protected void ObjectDataSource1_Updating(object sender, ObjectDataSourceMethodEventArgs e)
{
object o = ListView1.Items[ListView1.EditIndex].FindControl("txtQty");
if (o.GetType() == typeof(TextBox))
{
e.InputParameters[0] = ((TextBox)o).Text;
}

}
下面是ListView中的EditItemTemplate内容:
<EditItemTemplate>
<tr>
<td>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</td>
<td>
<asp:TextBox ID="txtQty" runat="server"></asp:TextBox>
</td>
<td>
<asp:LinkButton ID="LinkButton1" CommandName="Update" runat="server">Update</asp:LinkButton>
<asp:LinkButton CommandName="Cancel" ID="LinkButton2" runat="server">Cancel</asp:LinkButton>
</td>
</tr>
</EditItemTemplate>

ListView的使用Sample

<h3>ListView Templates Example</h3>
<asp:ListView ID="ContactsListView"
DataSourceID="ContactsDataSource"
DataKeyNames="ContactID"
runat="server">
<LayoutTemplate>
<table cellpadding="2" width="640px" border="1" runat="server" id="tblProducts">
<tr runat="server">
<th runat="server">Action</th>
<th runat="server">First Name</th>
<th runat="server">Last Name</th>
</tr>
<tr runat="server" id="itemPlaceholder" />
</table>
<asp:DataPager runat="server" ID="ContactsDataPager" PageSize="12">
<Fields>
<asp:NextPreviousPagerField ShowFirstPageButton="true" ShowLastPageButton="true"
FirstPageText="|<< " LastPageText=" >>|"
NextPageText=" > " PreviousPageText=" < " />
</Fields>
</asp:DataPager>
</LayoutTemplate>
<ItemTemplate>
<tr runat="server">
<td>
<asp:LinkButton ID="EditButton" runat="Server" Text="Edit" CommandName="Edit" />
</td>
<td>
<asp:Label ID="FirstNameLabel" runat="Server" Text='<%#Eval("FirstName") %>' />
</td>
<td valign="top">
<asp:Label ID="LastNameLabel" runat="Server" Text='<%#Eval("LastName") %>' />
</td>
</tr>
</ItemTemplate>
<EditItemTemplate>
<tr style="background-color: #ADD8E6">
<td>
<asp:LinkButton ID="UpdateButton" runat="server" CommandName="Update" Text="Update" />
<asp:LinkButton ID="CancelButton" runat="server" CommandName="Cancel" Text="Cancel" />
</td>
<td>
<asp:TextBox ID="FirstNameTextBox" runat="server" Text='<%#Bind("FirstName") %>'
MaxLength="50" /><br />
</td>
<td>
<asp:TextBox ID="LastNameTextBox" runat="server" Text='<%#Bind("LastName") %>'
MaxLength="50" /><br />
</td>
</tr>
</EditItemTemplate>
</asp:ListView>

2009年3月17日星期二

Refactor IBA Ecommerce Application

原先设想的是在MOSS端,只从Cache DB中取得数据,但经过最近的分析后,还需要通过Web Service从SAP端获得数据。而原来的Architecture并没有考虑到这个问题,因些需要对Architecture 进行Refactor。

使用SmartPart将UserControl引入SharePoint

SmartPart是一个SharePoint的Feature, 它可以使我们开发的Web UserControl直接在SharePoint 2007中的Web page中,以Web Part的形式显示,真是天才一样的作品,我认为都应该作为SharePoint的核心功能,否则开发SharePoint的Web Part实在是一件非常头痛的事情。

首先下载SmartPart安装包,然后上传至服务器,运行Setup.exe。在运行过程中可以选择要开启这个feature的站点。成功安装后,去相应的站点的Site Collection Feature中,把return of smartpart的feature active,就可以使用了。

首先,我们用VS2008创建一个Web usercontrol,它一共包含三个文件:
  • WebUserControl1.ascx
  • WebUserControl1.ascx.cs
  • WebUserControl1.ascx.designer
其中,一定要在WebUserControl1.ascx中做两处修改:
  1. 将<%@ Assembly Name="ReturnOfSmartPart, Version=1.3.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5" %>加入顶部,引用assembly。
  2. 修改<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="WebUserControl1.ascx.cs",将CodeBehind换成CodeFile
  3. 在类声明(public partial class WebUserControl1 : System.Web.UI.UserControl)前面加入:System.ComponentModel.Description("WebUserControl1")]。这样可以使SmartPart寻找的UserControl列表中显示自定义的User Control名称。
做了这两个修改后,在SharePoint的站点下,如VirtualDirectory/8080/下面,创建一个UserControls目录,这点非常重要,名字绝对不能有差。接着将上面的三个文件,直接放入这个文件夹内就可以了。

使用方法:
  1. 进入SharePoint的相应站点,Edit Page -> Add Webpart -> Add SmartPart Webpart
  2. Modify Shared Web Part
  3. 选择WebUserControl1对应的Webpart即可。

2009年3月9日星期一

[转]CHAR, VARCHAR, TEXT, NCHAR的不同

  1. CHAR。CHAR存储定长数据很方便,CHAR字段上的索引效率级高,比如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间,不足的自动用空格填充。
  2. VARCHAR。存储变长数据,但存储效率没有CHAR高。如果一个字段可能的值是不固定长度的,我们只知道它不可能超过10个字符,把它定义为 VARCHAR(10)是最合算的。VARCHAR类型的实际长度是它的值的实际长度+1。为什么“+1”呢?这一个字节用于保存实际使用了多大的长度。从空间上考虑,用varchar合适;从效率上考虑,用char合适,关键是根据实际情况找到权衡点。
  3. TEXT。text存储可变长度的非Unicode数据,最大长度为2^31-1(2,147,483,647)个字符。
  4. NCHAR、NVARCHAR、NTEXT。这三种从名字上看比前面三种多了个“N”。它表示存储的是Unicode数据类型的字符。我们知道字符中,英文字符只需要一个字节存储就足够了,但汉字众多,需要两个字节存储,英文与汉字同时存在时容易造成混乱,Unicode字符集就是为了解决字符集这种不兼容的问题而产生的,它所有的字符都用两个字节表示,即英文字符也是用两个字节表示。nchar、nvarchar的长度是在1到4000之间。和char、varchar比较起来,nchar、nvarchar则最多存储4000个字符,不论是英文还是汉字;而char、varchar最多能存储8000个英文,4000个汉字。可以看出使用nchar、nvarchar数据类型时不用担心输入的字符是英文还是汉字,较为方便,但在存储英文时数量上有些损失。
根据以上几个datatype的不同,由于Unicode编码比非Unicode编码要多很多字节,因此,不存在多语言的情况下,就尽量避免使用n开头的类型。

2009年3月5日星期四

使用SharePoint Designer 2007为Page创建DataView

应用场景:
某E-commerce系统需要一个显示零件信息的详细页面。在这个详细页面上,需要显示此零件的一些零件图。
页面预览:


技术实现:

左侧的Part基本信息是采用Custom Web Part来实现的,右侧的图像是使用Office SharePoint Designer 2007来实现的。具体的实现方法是:
  1. 创建一个用于显示Part Detial的PartDetial.aspx在Web Part Page (Docuemnt) library中。
  2. 创建一个Part Picture Library用于存放上传的Part Pictures.
  3. 为Part Picture Library创建一个新Column - PartID (Single Textbox)用于存放Part ID。此即为零件的唯一标识。
  4. 使用SharePoint Designer 打开sharepoint 站点,编辑PartDetail.aspx页面
  5. 在适当的位置(Web Part Zone)添加一个DataView
  6. 选择DataSource为Part Picture library
  7. 在Design页面中单击DataView旁边的小三角号,可显示操作菜单。
  8. 选择默认的Layout, 编辑Columns,加入合适的字段。对于Picture Library, 添加"URL Path"后会自动在页面上输出图像。
  9. 进入Filter管理器,新增加一个Filter为Part ID。并设置其根据QueryString来取得值。
  10. 保存页面(Check In)即可