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

<%@ 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>

                &nbsp;&nbsp;&nbsp;<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 />

                &nbsp;

            </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 />

       

         <%-- 数据源集中区  项目基类资源--%>

        &nbsp;<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 />

    &nbsp;

</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



    }

}

你可能感兴趣的:(project)