您的位置:首页 > 编程语言 > ASP

CSLA.Net 3.0.5 项目管理示例 UI ProjectEdit.aspx

2009-10-06 10:23 405 查看
<%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true"
CodeFile="ProjectEdit.aspx.cs" Inherits="PTWeb.ProjectEdit" Title="项目信息" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<div>
<asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
<!-- 视图1 -->
<asp:View ID="MainView" runat="server">
<!-- 提供项目编辑显示
AutoGenerateRows="False" 的好处在于可以优化访问,代码可以控制她的刷新,这样只在有更新的时候调用DataBind()方法刷新
-->
<asp:DetailsView ID="DetailsView1" runat="server" Height="50px" Width="536px" AutoGenerateRows="False"
DataSourceID="ProjectDataSource" DataKeyNames="Id" OnItemDeleted="DetailsView1_ItemDeleted"
OnItemInserted="DetailsView1_ItemInserted" OnItemUpdated="DetailsView1_ItemUpdated"
OnItemCreated="DetailsView1_ItemCreated">
<Fields>
<asp:BoundField DataField="Id" HeaderText="编号" ReadOnly="True" SortExpression="Id"
InsertVisible="False">
<ItemStyle Width="90%" />
</asp:BoundField>
<asp:BoundField DataField="Name" HeaderText="名字" SortExpression="Name">
<ControlStyle Width="90%" />
</asp:BoundField>
<asp:BoundField DataField="Started" HeaderText="开始时间" SortExpression="Started">
<ControlStyle Width="90%" />
</asp:BoundField>
<asp:BoundField DataField="Ended" HeaderText="结束时间" SortExpression="Ended">
<ControlStyle Width="90%" />
</asp:BoundField>
<%-- 描述是一个模板列,她提供了
编辑,添加,显示三种状态的显示模板

--%>
<asp:TemplateField HeaderText="描述" SortExpression="Description">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" TextMode="MultiLine" Width="90%" runat="server" Text='<%# Bind("Description") %>'></asp:TextBox>
</EditItemTemplate>
<InsertItemTemplate>
<asp:TextBox ID="TextBox1" TextMode="MultiLine" Width="90%" runat="server" Text='<%# Bind("Description") %>'></asp:TextBox>
</InsertItemTemplate>
<ItemTemplate>
<asp:TextBox ID="TextBox1" TextMode="MultiLine" ReadOnly="true" Width="90%" runat="server"
Text='<%# Bind("Description") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
   <br />
<!-- 提供相关项目的资源分派列表,也就是子表的显示  -->
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AutoGenerateColumns="False"
DataSourceID="ResourcesDataSource" Width="432px" DataKeyNames="ResourceId">
<Columns>
<asp:BoundField DataField="ResourceId" HeaderText="ResourceId" ReadOnly="True" SortExpression="ResourceId"
Visible="False" />
<%-- 显示的文本是
DataTextField="FullName" 全名
--%>
<asp:HyperLinkField DataNavigateUrlFields="ResourceId" DataNavigateUrlFormatString="ResourceEdit.aspx?id={0}"
DataTextField="FullName" HeaderText="名字" />
<asp:BoundField DataField="Assigned" HeaderText="分配" ReadOnly="True" SortExpression="Assigned" />
<%-- 提供了职务的模板,她是一个列表,
在编辑模式下 将其激活
显示模式下 将Enabled="False" 设置为假
DataTextField="Value" DataValueField="Key" 分别代表对象的数据源的属性
由于数据源是RoleList(名值对列表)
SelectedValue='<%# Bind("Role") %>'> 很关键,首先你要知道<%# Bind("Role") %>是什么,这个是GridView1的资源
这样这个属性是用于设置DDL(DropDownList)当前显示的项目是谁
--%>
<asp:TemplateField HeaderText="职务" SortExpression="Role">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="RoleListDataSource"
DataTextField="Value" DataValueField="Key" SelectedValue='<%# Bind("Role") %>'>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:DropDownList ID="DropDownList2" runat="server" DataSourceID="RoleListDataSource"
DataTextField="Value" DataValueField="Key" Enabled="False" SelectedValue='<%# Bind("Role") %>'>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
</Columns>
</asp:GridView>
<asp:LinkButton ID="AddResourceButton" runat="server" OnClick="AddResourceButton_Click">添加资源</asp:LinkButton><br />
<br />
 
</asp:View>
<!-- 视图2 -->
<asp:View ID="AssignView" runat="server">
<strong>选资源:</strong><br />
<!-- OnSelectedIndexChanged在点选一个项目之后被激发 -->
<asp:GridView ID="GridView2" runat="server" AllowPaging="True" AutoGenerateColumns="False"
DataKeyNames="Id" DataSourceID="ResourceListDataSource" OnSelectedIndexChanged="GridView2_SelectedIndexChanged">
<Columns>
<asp:BoundField DataField="Name" HeaderText="资源" ReadOnly="True" SortExpression="Name" />
<asp:CommandField ShowSelectButton="True" />
</Columns>
</asp:GridView>
<asp:LinkButton ID="CancelAssignButton" runat="server" OnClick="CancelAssignButton_Click">取消</asp:LinkButton><br />
<%--只读资源列表做数据源--%>
<csla:CslaDataSource ID="ResourceListDataSource" runat="server" TypeName="ProjectTracker.Library.ResourceList, ProjectTracker.Library"
OnSelectObject="ResourceListDataSource_SelectObject" TypeSupportsPaging="False"
TypeSupportsSorting="False">
</csla:CslaDataSource>
</asp:View>
</asp:MultiView>

<asp:Label ID="ErrorLabel" runat="server" ForeColor="Red"></asp:Label><br />

<%-- 数据源集中区  项目基类资源--%>
 <csla:CslaDataSource ID="ProjectDataSource" runat="server" TypeName="ProjectTracker.Library.Project, ProjectTracker.Library"
OnDeleteObject="ProjectDataSource_DeleteObject" OnInsertObject="ProjectDataSource_InsertObject"
OnSelectObject="ProjectDataSource_SelectObject" OnUpdateObject="ProjectDataSource_UpdateObject"
TypeSupportsPaging="False" TypeSupportsSorting="False">
</csla:CslaDataSource>

<%-- 用的项目分配类,维护分配关系 --%>
<csla:CslaDataSource ID="ResourcesDataSource" runat="server" TypeName="ProjectTracker.Library.ProjectResources, ProjectTracker.Library"
OnDeleteObject="ResourcesDataSource_DeleteObject" OnSelectObject="ResourcesDataSource_SelectObject"
OnUpdateObject="ResourcesDataSource_UpdateObject" TypeSupportsPaging="False"
TypeSupportsSorting="False">
</csla:CslaDataSource>

<%-- 名值对类表 --%>
<csla:CslaDataSource ID="RoleListDataSource" runat="server" TypeName="ProjectTracker.Library.RoleList, ProjectTracker.Library"
OnSelectObject="RoleListDataSource_SelectObject" TypeSupportsPaging="False" TypeSupportsSorting="False">
</csla:CslaDataSource>
<br />
</div>
<br />
 
</asp:Content>




 

//======================================================================
//
//        Guid1:               91a22c9c-c56a-4986-8ea5-d3db474ed789
//        CLR版本:             2.0.50727.3053
//        新建项输入的名称:    ProjectEdit
//        机器名称:            SOFTWARE-FRT-08
//        命名空间名称:        PTWeb
//        文件名:              ProjectEdit
//        当前系统时间:        2008-10-2 19:07:41
//        用户所在的域:        TECHSTAR
//        当前登录用户名:      frt
//        创建年份:            2008
//
//        Created by Terry.Feng.C (冯瑞涛) at 2008-10-2 19:07:41
//
//
//======================================================================

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using ProjectTracker.Library;

namespace PTWeb
{
public partial class ProjectEdit : System.Web.UI.Page
{
#region 私有成员
private enum Views
{
MainView = 0,
AssignView = 1
}

private void ApplyAuthorizationRules()
{
Project obj = GetProject();
// 项目
if (Project.CanEditObject())
{
if (obj.IsNew)
this.DetailsView1.DefaultMode = DetailsViewMode.Insert;
else
this.DetailsView1.DefaultMode = DetailsViewMode.Edit;

//新的是不显示的,因为此时这个项目还没有被实际存在(数据库中没有)

//***其实在这里我有一些自己的看法
//如果我们能够不在保存父对象的情况下,可以为其添加和建立子对象,将结果缓存起来,最后我们在父对象上点击保存,结果是把所有的父子,全都保存
//CSLA的演示程序,在这里她并不是这样的,但是她是支持的,如果你没有建立一个父对象她是不会让你为其添加资源的,她没有这么实现,
//你可以看一下GridView2_SelectedIndexChanged这个事件,他在这里进行了保存SaveProject,如果我们不调用它,是可以的,成功了!
//
// 注意! 理解Session和Obj是出于同一个引用是这次的关键!在98行
//
//在这里我分析了她当前能否实现这个需求,
//1。他们的父子关系是多对多的关系,所以他们之间的分配是建立在一个中间表中的,这样中间表是需要父子两个表的主键为主键的

//this.AddResourceButton.Visible = !obj.IsNew;
}
else
{
this.DetailsView1.DefaultMode = DetailsViewMode.ReadOnly;
this.AddResourceButton.Visible = false;
}

//这两个控件都是视图1中的
//由于Detailview是横向的,所以她是Rows.Count-1是最下面的控制行
this.DetailsView1.Rows[this.DetailsView1.Rows.Count - 1].Visible = Project.CanEditObject();

// 资源
// 最后一列根据权限同步显示
this.GridView1.Columns[this.GridView1.Columns.Count - 1].Visible = Project.CanEditObject();
}

/// <summary>
/// 获得,并缓存一个项目对象
/// </summary>
/// <returns></returns>
private Project GetProject()
{
//从缓存中取出项目对象
//这里Session,将内容付给Object,实际上是将一个引用传递,那么这代表这,如果Object这个对象,也就是GetProject返回的这个对象改变,同时也会影响
//Session["currentObject"] 的值,这是一个突破的理解,你在导出Session的活动,实际上就是在用另一种形式在使用Session的内容
object businessObject = Session["currentObject"]; //Session

//如果不存在,进入
if (businessObject == null || !(businessObject is Project))
{
try
{
string idString = Request.QueryString["id"];
//不是空的,代表是编辑或者是显示方法进来的
if (!string.IsNullOrEmpty(idString))
{
//根据参数建立一个Guid
Guid id = new Guid(idString);
//获得这个项目
businessObject = Project.GetProject(id);
}
else     //是新建进来的
businessObject = Project.NewProject();

//最后都要把这个对象付给缓存Session
Session["currentObject"] = businessObject; //====Session
}
catch (System.Security.SecurityException)
{
Response.Redirect("ProjectList.aspx");
}
}
//将当前对象返回
return (Project)businessObject; //在此加断点,用监视器监控Session["currentObject"]的变化
}

/// <summary>
/// 这个方法用于保存一个工程,并将结果缓存,实际上,这个工程只是扩展了异常捕获的范围,(556)
/// </summary>
/// <param name="project"></param>
/// <returns></returns>
private int SaveProject(Project project)
{
//要返回的行影响标记
int rowsAffected;
//返回
try
{
//保存,并缓存
Session["currentObject"] = project.Save();//====Session
//标记设置成功,就是说数据有改变
rowsAffected = 1;
}
//权限异常(559)
catch (Csla.Validation.ValidationException ex)
{
//字符串制造对象
System.Text.StringBuilder message = new System.Text.StringBuilder();
//先将获取的消息,添加进来
message.AppendFormat("{0}<br/>", ex.Message);
//有问题规则列表如果有一个,就直接显示
if (project.BrokenRulesCollection.Count == 1)
message.AppendFormat("* {0}: {1}", project.BrokenRulesCollection[0].Property, project.BrokenRulesCollection[0].Description);
else
//否则是多个,就用循环取出问题规则,主要是这个字符串加了<br/>,上面的无需加换行,否则是无需判断的
foreach (Csla.Validation.BrokenRule rule in project.BrokenRulesCollection)
message.AppendFormat("* {0}: {1}<br/>", rule.Property, rule.Description);
//将问题显示
this.ErrorLabel.Text = message.ToString();
rowsAffected = 0;
}
//数据门户异常
catch (Csla.DataPortalException ex)
{
this.ErrorLabel.Text = ex.BusinessException.Message;
rowsAffected = 0;
}
//最后的异常
catch (Exception ex)
{
this.ErrorLabel.Text = ex.Message;
rowsAffected = 0;
}
return rowsAffected;
}

#endregion

#region 事件方法

protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//设置授权
ApplyAuthorizationRules();
}
else

this.ErrorLabel.Text = string.Empty;
}

#endregion

#region 数据控制

#region ProjectDataSource
/// <summary>
/// 项目Detailview在删除的时候激发这个事件,这个事件在这里好像很难用上
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void ProjectDataSource_DeleteObject( object sender, Csla.Web.DeleteObjectArgs e)
{
try
{
Project.DeleteProject(new Guid(e.Keys["Id"].ToString()));
//清空是为了重新加载
Session["currentObject"] = null; ////====Session
e.RowsAffected = 1;
}
catch (Csla.DataPortalException ex)
{
this.ErrorLabel.Text = ex.BusinessException.Message;
e.RowsAffected = 0;
}
catch (Exception ex)
{
this.ErrorLabel.Text = ex.Message;
e.RowsAffected = 0;
}
}

/// <summary>
/// Detailview在插入的时候引发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void ProjectDataSource_InsertObject(  object sender, Csla.Web.InsertObjectArgs e)
{
Project obj = GetProject();
Csla.Data.DataMapper.Map(e.Values, obj, "Id");
e.RowsAffected = SaveProject(obj);
}

/// <summary>
/// 对象的一次数据绑定,会引发这个事件
/// 要注意的一点是,如果你是点击新建进入这个页面的,在页面加载的时候也是会调用这个事件,为Detailview建立一个新的项目对象的
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void ProjectDataSource_SelectObject(object sender, Csla.Web.SelectObjectArgs e)
{
e.BusinessObject = GetProject();
}

/// <summary>
/// 当Detailview更新的时候激发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void ProjectDataSource_UpdateObject(object sender, Csla.Web.UpdateObjectArgs e)
{
Project obj = GetProject();
Csla.Data.DataMapper.Map(e.Values, obj);
//调用保存方法,她扩展了异常的捕获
e.RowsAffected = SaveProject(obj);
}

#endregion

#region ResourcesDataSource
/// <summary>
/// ResourcesDataSource是
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void ResourcesDataSource_DeleteObject( object sender, Csla.Web.DeleteObjectArgs e)
{
Project obj = GetProject();
int rid = int.Parse(e.Keys["ResourceId"].ToString());
obj.Resources.Remove(rid);
e.RowsAffected = SaveProject(obj);
}

/// <summary>
/// 当可编辑资源列表加载的时候引发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void ResourcesDataSource_SelectObject( object sender, Csla.Web.SelectObjectArgs e)
{
Project obj = GetProject();
//获得当前项目的所有资源
e.BusinessObject = obj.Resources;
}

/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void ResourcesDataSource_UpdateObject( object sender, Csla.Web.UpdateObjectArgs e)
{
//获得当前项目
Project obj = GetProject();
//获得更新的资源id
int rid = int.Parse(e.Keys["ResourceId"].ToString());
//通过父对象获得她的资源引用
ProjectResource res = obj.Resources.GetItem(rid);
//拷贝数据
Csla.Data.DataMapper.Map(e.Values, res);
//立即保存,
e.RowsAffected = SaveProject(obj);
}

#endregion

#region ResourceListDataSource
/// <summary>
/// ResourceListDataSource 是选择列表的资源,当载入一个对象的时候激发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void ResourceListDataSource_SelectObject(  object sender, Csla.Web.SelectObjectArgs e)
{
//只读列表
e.BusinessObject = ProjectTracker.Library.ResourceList.GetResourceList();
}

#endregion

#region RoleListDataSource
/// <summary>
/// RoleListDataSource是在给一个项目现在资源后,配置这个资源的职务的时候的那个下拉列表框,同样在加载的时候激发
/// 这个事件估计用的会很多,因为每一个被分配的资源记录都要计划一次她,来初始化对象的职务列表
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void RoleListDataSource_SelectObject( object sender, Csla.Web.SelectObjectArgs e)
{
//调用名只对列表
e.BusinessObject = RoleList.GetList();
}

#endregion

#endregion

#region 界面控制
#region Project DetailsView

/// <summary>
/// 在DetailsView控件初始化后,激发,用于填充数据
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void DetailsView1_ItemCreated(object sender, EventArgs e)
{
//校验模式,如果是录入模式这个录入才能成功,才是有意义的
if (DetailsView1.DefaultMode == DetailsViewMode.Insert)
{
//调用私有方法,获取这个对象,这个也许是空值的,也许也是编辑的
Project obj = GetProject();
//将第二行的第二列的第一个控件的Text属性设置值,要知道是从0开始数的,而这里也没有什么控件,这里是Details的格子控件,没有名字用位置描述
((TextBox)DetailsView1.Rows[1].Cells[1].Controls[0]).Text = obj.Name;
//将第三行的第二列的第一个控件的Text属性设置值
((TextBox)DetailsView1.Rows[2].Cells[1].Controls[0]).Text = obj.Started;
//将第四行的第二列的第一个控件的Text属性设置值
((TextBox)DetailsView1.Rows[3].Cells[1].Controls[0]).Text = obj.Ended;

//发现DetailsView1.中的名字为TextBox控件的设置Text属性
((TextBox)DetailsView1.FindControl("TextBox1")).Text = obj.Description;
}
}
/// <summary>
/// 在Details点击插入的之后,MSDN:在单击 DetailsView 控件中的“插入”按钮时,但在插入操作之后发生。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void DetailsView1_ItemInserted(object sender, DetailsViewInsertedEventArgs e)
{
Project project = GetProject();

//如果不是新的则跳转
if (!project.IsNew)
Response.Redirect("ProjectEdit.aspx?id=" + project.Id.ToString());
}
/// <summary>
/// 在单击 DetailsView 控件中的“更新”按钮时,但在更新操作之后发生。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void DetailsView1_ItemUpdated(  object sender, DetailsViewUpdatedEventArgs e)
{
ApplyAuthorizationRules();
}

/// <summary>
/// 在单击 DetailsView 控件中的“删除”按钮时,但在删除操作之后发生。实际上这个事件是不会发生的,因为没有删除按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void DetailsView1_ItemDeleted( object sender, DetailsViewDeletedEventArgs e)
{
Response.Redirect("ProjectList.aspx");
}

#endregion

#region Resource Grid

/// <summary>
/// 点击为项目添加一个资源按钮,切换视图
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void AddResourceButton_Click( object sender, EventArgs e)
{
this.MultiView1.ActiveViewIndex =(int)Views.AssignView;
}

/// <summary>
/// GridView2是资源选择类表控件,当选择一个选项后激发此事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void GridView2_SelectedIndexChanged( object sender, EventArgs e)
{
//获取当前的项目对象
Project obj = GetProject();
try
{
//将选中的主键转换成整型,分配给自己
//GridView2.SelectedDataKey.Value 代表,被选中项目的主键的值(559)
obj.Resources.Assign(int.Parse( this.GridView2.SelectedDataKey.Value.ToString()));
//调用私有保存方法,如果返回不是0,成功,则刷新视图1的资源列表,并切换回主页面
//注销下面的if可以支持延迟保存

//if (SaveProject(obj) > 0)
//{
this.GridView1.DataBind();
this.MultiView1.ActiveViewIndex = (int)Views.MainView;
//}
}
//如果你选中了已经存在的子对象(重复分配),Assign会发出一个异常,这个异常会在这里被捕获,处理的方法是将这个异常付给ErrorLabel显示给用户
catch (InvalidOperationException ex)
{
ErrorLabel.Text = ex.Message;
}
}

/// <summary>
/// 在分配选择资源的时候点击取消,切回视图
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void CancelAssignButton_Click(object sender, EventArgs e)
{
this.MultiView1.ActiveViewIndex = (int)Views.MainView;
}

#endregion

#endregion

}
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: