--- name: dev-asp-net description: DevExpress 25.1.6.0을 활용한 ASP.NET 웹 페이지 개발 전문가 스킬. ASP.NET Web Forms, MVC 패턴, DevExpress Bootstrap 컨트롤, Bootstrap 반응형 디자인 작업 시 사용. (1) ASP.NET 웹 페이지 생성, (2) DevExpress Bootstrap 컨트롤(BootstrapGridView, BootstrapComboBox, BootstrapDateEdit, BootstrapButton, BootstrapSpinEdit 등) 구현, (3) XPO DataBinding 설정, (4) PopupEditForm 편집 패턴 구현, (5) Code-behind 작성 시 사용. --- # DevAspNet Skill DevExpress Bootstrap 25.1.6.0 기반 ASP.NET 웹 개발 가이드. ## 핵심 원칙 ### 아키텍처 패턴 - **MVC 패턴**: Controller에서 비즈니스 로직, View에서 UI 분리 - **DataBinding**: List 기반 바인딩, 세션 캐싱 활용 - **반응형 디자인**: Bootstrap 5.3 + DevExpress Bootstrap 컨트롤 ### 코드 작성 규칙 1. **ASPX 주석**: `<%-- 주석 --%>` (HTML 주석 금지) 2. **한글 주석**: 복잡한 로직에 필수 3. **File Encoding**: 한글이 안깨지도록 UTF-8로 저장 4. **출력 형식**: 변경 파일 리스트와 소스만 제공 5. **문서**: 최소한의 요약 md만 생성 ## DevExpress Bootstrap 컨트롤 ### Register 지시문 ```aspx <%@ Register Assembly="DevExpress.Web.Bootstrap.v25.1, Version=25.1.6.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" Namespace="DevExpress.Web.Bootstrap" TagPrefix="dx" %> ``` ### BootstrapGridView 기본 구조 ```aspx <%-- 컬럼 정의 --%> ``` ### BootstrapGridView 컬럼 타입 ```aspx <%-- 텍스트 컬럼 --%> <%-- 날짜 컬럼 --%> <%-- 숫자(SpinEdit) 컬럼 --%> <%-- 명령 버튼 컬럼 --%> <%-- 숨김 Key 컬럼 --%> ``` ### PopupEditForm 설정 ```aspx <%-- PopupEditForm 방식 설정 --%> <%-- EditForm 템플릿 --%>
완료일
계획 M/H
``` ### 클라이언트 메시지 콜백 패턴 ```aspx ``` ### BootstrapComboBox ```aspx <%-- AutoPostBack 사용 시 --%> ``` ### BootstrapDateEdit ```aspx ``` ### BootstrapButton ```aspx <%-- Primary 버튼 (아이콘 포함) --%> <%-- 확인 다이얼로그 --%> ``` ## Code-behind 패턴 ### 기본 구조 ```csharp using DevExpress.Web; using DevExpress.Web.Bootstrap; using DevExpress.Web.Data; public partial class ToDoList : System.Web.UI.Page { private ToDoListController _controller = new ToDoListController(); private const string SESSION_KEY_DATA = "ToDoList_Data"; // 세션 기반 그리드 데이터 관리 private List GridData { get { return Session[SESSION_KEY_DATA] as List; } set { Session[SESSION_KEY_DATA] = value; } } protected void Page_Load(object sender, EventArgs e) { // 로그인 체크 if (Session["UserID"] == null) { Response.Redirect("Login.aspx", false); Context.ApplicationInstance.CompleteRequest(); return; } if (!IsPostBack && !IsCallback) InitializePage(); else BindGridFromSession(); } } ``` ### 복합 키 RowUpdating 처리 (중요!) ```csharp protected void grid_RowUpdating(object sender, ASPxDataUpdatingEventArgs e) { // List 데이터소스는 기본 업데이트 미지원 → 항상 Cancel e.Cancel = true; try { // 복합키: e.Keys로 접근 (e.OldValues 아님!) string companyNo = e.Keys["COMPANY_NO"]?.ToString(); string caseNo = e.Keys["CASE_NO"]?.ToString(); string projectNo = e.Keys["PROJECT_NO"]?.ToString(); string orderNo = e.Keys["ORDER_NO"]?.ToString(); // 수정 필드: e.NewValues로 접근 DateTime? compDate = e.NewValues["COMP_DATE"] as DateTime?; decimal? planMhr = e.NewValues["PLAN_MHR"] as decimal?; bool result = _controller.UpdateWorkOrder( caseNo, companyNo, projectNo, orderNo, compDate, planMhr, userId); if (result) { // 성공 시: 팝업 닫고 데이터 새로고침 gridToDoList.CancelEdit(); LoadData(); ShowMessageCallback("데이터가 수정되었습니다."); } } catch (Exception ex) { ShowMessageCallback($"수정 오류: {ex.Message}"); } } ``` ### 콜백 메시지 표시 ```csharp // 일반 메시지 private void ShowMessage(string message) { string script = $"alert('{message.Replace("'", "\\'")}');"; ScriptManager.RegisterStartupScript(this, GetType(), "alertScript", script, true); } // 콜백 모드 메시지 (JSProperties 사용) private void ShowMessageCallback(string message) { gridToDoList.JSProperties["cpMessage"] = message; } ``` ### 세션 바인딩 ```csharp private void BindGridFromSession() { if (GridData != null) { gridToDoList.DataSource = GridData; gridToDoList.DataBind(); } } ``` ### 행 삭제 (FocusedRow 사용) ```csharp protected void btnDelete_Click(object sender, EventArgs e) { if (gridToDoList.FocusedRowIndex < 0) { ShowMessage("삭제할 데이터를 선택하세요."); return; } // 복합키 가져오기 object[] keyValues = (object[])gridToDoList.GetRowValues( gridToDoList.FocusedRowIndex, new string[] { "COMPANY_NO", "CASE_NO", "PROJECT_NO", "ORDER_NO" }); string companyNo = keyValues[0]?.ToString(); string caseNo = keyValues[1]?.ToString(); // ... } ``` ## 주의사항 1. **ASPxGridView vs BootstrapGridView**: 이 프로젝트는 `BootstrapGridView` 사용 2. **PopupEditForm 성공 시**: `gridToDoList.CancelEdit()` 호출로 팝업 닫기 3. **복합 키**: `KeyFieldName="Key1;Key2;Key3"` 세미콜론 구분, `e.Keys`로 접근 4. **List 데이터소스**: `e.Cancel = true` 필수 (기본 업데이트 미지원) 5. **콜백 메시지**: `JSProperties["cpMessage"]` + `EndCallback` 이벤트 조합