문서의 이전 판입니다!
목차
UBi 프레임워크 업무화면(UX) 템플릿 분석
문서 정보
* 작성일: 2026-03-21
* 대상: UBi3 Framework 기반 업무화면 개발자
* 템플릿: UBi_FORM_SEC
* 프레임워크 버전: UBi3 / .NET Framework 4.7.2
1. 개요
UBi 프레임워크는 유비덤(UBiDum)에서 개발한 WinForm 기반 업무화면 개발 프레임워크입니다. 개발자는 UBi_FORM_SEC 템플릿 프로젝트를 복사하여 새로운 업무화면을 빠르게 구성할 수 있습니다.
1.1 기술 스택
| 구분 | 기술/버전 |
| 런타임 | .NET Framework 4.7.2 |
| UI 컨트롤 | DevExpress v20.1 |
| 프레임워크 | UBi3 Framework (UBi.WinForm.Controls) |
| 데이터 통신 | REST API (UBi.Net.RestfulClient) |
| DB 프로시저 | Oracle Stored Procedure (PKG 패턴) |
| 프로젝트 형태 | Class Library (DLL) |
1.2 프레임워크 주요 DLL
| DLL 명칭 | 역할 |
| UBi.dll | 코어 유틸리티, 확장 메서드 (Nvl 등) |
| UBi.IO.dll | 파일 입출력 처리 |
| UBi.Net.dll | 네트워크 통신 기반 |
| UBi.Net.RestfulClient.dll | REST API 클라이언트 |
| UBi.Net.Sockets.dll | 소켓 통신 |
| UBi.Platform.dll | 플랫폼 공통 기능 |
| UBi.Platform.Images.dll | 이미지 처리 |
| UBi.WinForm.dll | WinForm 기반 클래스 |
| UBi.WinForm.Controls.dll | UI 컨트롤 (BaseModule, DataManager 등) |
2. 프로젝트 구성
2.1 템플릿 폴더 구조
UBi_FORM_SEC/ ├── Properties/ │ ├── AssemblyInfo.cs ← 어셈블리 메타정보 (프로젝트명, 설명) │ ├── licenses.licx ← DevExpress 라이선스 │ ├── Resources.resx ← 리소스 정의 │ └── Resources.Designer.cs ← 리소스 자동 생성 코드 ├── UBi_FORM_SEC.cs ← ★ 메인 비즈니스 로직 (개발자 작성 영역) ├── UBi_FORM_SEC.Designer.cs ← ★ 디자이너 코드 (Visual Studio 디자이너) ├── UBi_FORM_SEC.resx ← 폼 리소스 └── UBi_FORM_SEC.csproj ← 프로젝트 파일
2.2 핵심 파일 설명
UBi_FORM_SEC.cs (메인 로직)
개발자가 직접 코드를 작성하는 파일입니다. BaseModule을 상속받아 업무화면을 구현합니다.
UBi_FORM_SEC.Designer.cs (디자이너)
Visual Studio 디자이너가 자동 생성하는 파일입니다. 컨트롤 배치, DataAdapter 설정, 컬럼 정의 등이 포함됩니다.
UBi_FORM_SEC.csproj (프로젝트 설정)
빌드 설정, 참조 DLL, PostBuild 이벤트(afterbuild) 등을 정의합니다.
3. 새 업무화면 생성 절차
3.1 Step 1: 템플릿 복사
UBi_FORM_SEC폴더를 복사합니다- 폴더명을 새 업무화면 ID로 변경합니다 (예:
UBi_FORM_ORD001) - 폴더 내 모든 파일명에서
UBi_FORM_SEC를 새 이름으로 변경합니다
예) UBi_FORM_SEC → UBi_FORM_ORD001
UBi_FORM_SEC.cs → UBi_FORM_ORD001.cs
UBi_FORM_SEC.Designer.cs → UBi_FORM_ORD001.Designer.cs
UBi_FORM_SEC.csproj → UBi_FORM_ORD001.csproj
UBi_FORM_SEC.resx → UBi_FORM_ORD001.resx
3.2 Step 2: 클래스명 변경
UBi_FORM_SEC.cs와 UBi_FORM_SEC.Designer.cs 파일에서 클래스명을 변경합니다.
// 변경 전 public partial class 프로젝트명을지정하시오 : BaseModule // 변경 후 (예시) public partial class UBi_FORM_ORD001 : BaseModule
주의: .cs 파일과 .Designer.cs 파일 모두에서 클래스명을 동일하게 변경해야 합니다.
3.3 Step 3: 문서 주석 작성
클래스 상단의 XML 주석을 작성합니다.
/// <summary> /// 주문등록 화면 /// 고객 주문을 등록하고 관리하는 화면입니다. /// 작성자 : 홍길동 /// 작성일 : 2026-03-21 /// </summary> [ToolboxItem(false)] public partial class UBi_FORM_ORD001 : BaseModule
3.4 Step 4: AssemblyInfo.cs 수정
Properties/AssemblyInfo.cs에서 어셈블리 정보를 수정합니다.
[assembly: AssemblyTitle("UBi_FORM_ORD001")] [assembly: AssemblyDescription("주문등록 화면")]
3.5 Step 5: 솔루션에 프로젝트 추가
- Visual Studio에서 솔루션 열기
- 솔루션 탐색기 → 우클릭 → 기존 프로젝트 추가
- 새로 만든
.csproj파일 선택
4. 아키텍처 및 핵심 컴포넌트
4.1 클래스 상속 구조
System.Windows.Forms.UserControl
└─ BaseModule (UBi.WinForm.Controls)
└─ 업무화면 클래스 (개발자 작성)
BaseModule은 MDI 자식 폼으로 동작하며, 공통 버튼 인터페이스(IButton)를 제공합니다.
4.2 UBiDataManager (데이터 매니저)
화면의 데이터 접근을 총괄하는 컴포넌트입니다.
| 속성 | 설명 | 예시값 |
| ServiceUrl | REST API 서버 주소 | http://localhost:5000/api |
| ServiceName | DB 서비스 구분 이름 | SEC_DEV |
| ServiceUserId | 서비스 접속 사용자 ID | a |
| ServicePassword | 서비스 접속 비밀번호 | a |
| IsFullLoad | 전체 로드 여부 | false |
| AdapterList | 하위 DataAdapter 목록 | - |
초기화 방법:
// Form_Load에서 호출 uBiDataManager1.Init(); // → IsOnLoadSelect="Y"인 DataAdapter가 자동으로 SELECT 프로시저 실행
4.3 UBiDataAdapter (데이터 어댑터)
개별 데이터 세트(DataSet)에 대한 CRUD 작업을 담당합니다.
| 속성 | 설명 |
| NAME | 어댑터 식별자 (예: “TEST”) |
| DESCRIPTION | 어댑터 설명 |
| IsRoot | 루트 어댑터 여부 |
| IsOnLoadSelect | 화면 로드 시 자동 조회 여부 (“Y”/“N”) |
| MODE | 데이터 모드 (STATIC 등) |
| SELECT_PROCEDURE_ID | 조회 프로시저 이름 (예: PKG_SYS$GET_CHILDS) |
| INSERT_PROCEDURE_ID | 입력 프로시저 이름 |
| UPDATE_PROCEDURE_ID | 수정 프로시저 이름 |
| DELETE_PROCEDURE_ID | 삭제 프로시저 이름 |
| LookupLayOut | 컬럼 속성 정의 목록 (UBiColProperty) |
| SelectParam | 조회 파라미터 목록 (UBiParam) |
프로시저 호출 규칙
Oracle 저장 프로시저는 패키지 형태로 관리됩니다.
명명규칙: PKG_{업무구분}${프로시저명}
예시: PKG_SYS$GET_CHILDS
파라미터(UBiParam) 구조
| 속성 | 설명 | 예시 |
| ARGUMENT_NAME | 프로시저 파라미터 이름 | A_PARENT_PATH |
| DATA_TYPE | 데이터 타입 | VARCHAR / INT |
| DATA_LENGTH | 데이터 길이 | 200 |
| IN_OUT | 입출력 방향 | IN / OUT |
| IS_FIND | 조건 검색 사용 여부 | true |
| SORT_ORDER | 파라미터 순서 | 1, 2, 3… |
| SOURCE_NAME | 소스 바인딩 이름 | A_PARENT_PATH |
표준 OUT 파라미터:
모든 프로시저는 다음 OUT 파라미터를 포함합니다:
N_RETURN(INT) — 결과 코드 (0: 성공)V_RETURN(VARCHAR, 4000) — 결과 메시지
4.4 UBiColProperty (컬럼 속성)
그리드 및 Lookup 컬럼의 속성을 정의합니다.
| 속성 | 설명 | 예시 |
| FIELD_NAME | DB 컬럼명 | DATA_ID |
| TITLE | 화면 표시 제목 | 데이터번호 |
| TITLE_ID | 다국어 제목 ID | DATA_ID |
| DATA_TYPE | 데이터 타입 | System.Int64, System.String, System.Decimal |
| COL_TYPE | 컬럼 표시 유형 | NUMERIC (기본은 TEXT) |
| DATA_ALIGN | 정렬 방식 | Near(좌), Far(우) |
| SIZE | 컬럼 너비 | 80 |
| ORDER | 표시 순서 (10단위 증가) | 10, 20, 30… |
| BACK_COLOR | 배경색 | System.Drawing.Color.White |
| FORE_COLOR | 글자색 | System.Drawing.Color.Black |
4.5 UBiLayoutControl (레이아웃 컨트롤)
DevExpress의 LayoutControl을 확장한 컨트롤로, 화면의 전체 레이아웃을 관리합니다. Dock = Fill 모드로 폼 전체를 차지하며, 내부에 조회조건 영역과 데이터 그리드 등을 배치합니다.
5. 버튼 인터페이스 (IButton)
BaseModule은 MDI 프레임(UBiMdiForm)의 공통 툴바 버튼과 연결되는 가상 메서드를 제공합니다. 개발자는 필요한 메서드만 override하여 구현합니다.
5.1 버튼 메서드 일람
| 메서드 | 기능 | 설명 |
OnInitClick | 초기화 | 조회조건 초기화 등 화면 리셋 |
OnSearchClick | 조회 | DataAdapter.Select() 호출 |
OnAddClick | 추가 | 그리드 행 추가 등 |
OnDeleteClick | 삭제 | 그리드 행 삭제 등 |
OnSaveClick | 저장 | DataAdapter.Update() 호출 |
OnHelpClick | 도움말 | PDF 매뉴얼 표시 |
OnCloseClick | 닫기 | 화면 종료 시 정리 작업 |
5.2 조회 버튼 구현 예시
public override void OnSearchClick(UBiMdiForm f) { base.OnSearchClick(f); try { UBiMessageBox.ShowWait("Loading...", "Loading..."); // 방법 1: 컨트롤에서 직접 호출 gridMain.DataAdapter.Select(true); // 방법 2: DataManager에서 이름으로 호출 // uBiDataManager1.GetAdapter("TEST").Select(true); } catch (Exception ex) { ex.UBiShowException(this); } finally { UBiMessageBox.CloseWait(); } }
5.3 저장 버튼 구현 예시
public override void OnSaveClick(UBiMdiForm f) { base.OnSaveClick(f); try { UBiMessageBox.ShowWait("Wait", "Saving into Database..."); // 저장 전 유효성 검사 // ... ResponseDB res = gridMain.DataAdapter.Update(); if (res.Code == 0) { UBiMessageBox.Show(res.Message, MessageBoxIcon.Information, true); OnSearchClick(f); // 재조회 } else { UBiMessageBox.Show(res.Message, MessageBoxIcon.Error, true); } } catch (Exception ex) { ex.UBiShowException(this); } finally { UBiMessageBox.CloseWait(); } }
6. 그리드 이벤트 처리
UBi 프레임워크의 그리드(UBiGridView)는 DevExpress GridView를 확장한 컨트롤입니다. 다양한 이벤트를 통해 셀 편집, 스타일링, 합계 계산 등을 처리할 수 있습니다.
6.1 셀 값 변경 이벤트 (CellValueChanged)
특정 컬럼의 값이 변경되었을 때 처리합니다.
gridMain.CellValueChanged += (a, b) => { if (b.Column.FieldName.Equals("IS_CHK")) { // 체크박스 변경 시 처리 코드 } };
6.2 조건부 행 스타일 (RowCellStyle)
데이터 값에 따라 셀의 글자색, 배경색 등을 동적으로 변경합니다.
gridMain.RowCellStyle += (a, b) => { if (b.RowHandle >= 0) { UBiGridView view = a as UBiGridView; // 수량이 0보다 크면 파란색 if (view.GetRowCellValue(b.RowHandle, "PLAN_QTY").Nvl("0").ToInt() > 0) { b.Appearance.ForeColor = Color.Blue; } // 특정 컬럼 값에 따라 빨간색 if (b.Column.FieldName.Equals("ISBUY")) { if (b.CellValue.Nvl("N").Equals("Y")) b.Appearance.ForeColor = Color.Red; } } };
6.3 셀 편집 제한 (ShowingEditor)
특정 조건에서 셀 편집을 막아야 할 때 사용합니다.
gridMain.ShowingEditor += (a, b) => { if (gridMain.GetFocusedDataRow()["INPUT_LOCK"].Nvl("Y").Equals("Y")) { b.Cancel = true; UBiMessageBox.Show("투입 LOCK이 걸려 있습니다.", MessageBoxIcon.Information, false); SystemSounds.Beep.Play(); return; } };
6.4 조건부 커스텀 합계 (CustomSummaryCalculate)
특정 조건을 만족하는 행만 합계에 포함시킬 때 사용합니다.
decimal sumAMT = 0; gridMain.CustomSummaryCalculate += (a, b) => { gridSub.UpdateCurrentRow(); if (!b.IsTotalSummary || !((b.Item as GridSummaryItem).FieldName == "AMT")) return; if (b.SummaryProcess == DevExpress.Data.CustomSummaryProcess.Start) { sumAMT = 0; } if (b.SummaryProcess == DevExpress.Data.CustomSummaryProcess.Calculate) { if (b.Row is DataRowView r) { if (r.Row["END_CHK"].Nvl().Equals("Y")) { if ((b.Item as GridSummaryItem).FieldName == "AMT") sumAMT += (decimal)b.FieldValue; } } } if (b.SummaryProcess == DevExpress.Data.CustomSummaryProcess.Finalize) { if ((b.Item as GridSummaryItem).FieldName == "AMT") b.TotalValue = sumAMT; } };
6.5 기타 유용한 그리드 메서드
| 메서드/속성 | 기능 |
gridMain.ClearColumnsFilter() | 그리드 필터 조건 초기화 |
gridMain.GetFocusedDataRow() | 현재 포커스 행의 DataRow 반환 |
gridMain.UpdateCurrentRow() | 현재 행 데이터 갱신 |
7. 화면 간 파라미터 전달
화면이 호출될 때 부모 화면에서 전달하는 파라미터를 Param 속성으로 접근합니다.
private void Form_Load(object sender, EventArgs e) { if (Param != null) { // 파라미터 접근 string message = Param["message"].Nvl(); UBiMessageBox.Show(message, MessageBoxIcon.Information, true); } uBiDataManager1.Init(); }
파라미터 전달 패턴
| 메서드 | 설명 |
Param[“키”] | 문자열 값 가져오기 |
.Nvl() | null 안전 변환 (빈 문자열) |
.Nvl(“기본값”) | null일 때 기본값 반환 |
.ToInt() | 정수 변환 |
8. 공통 유틸리티
8.1 UBiMessageBox
| 메서드 | 설명 |
UBiMessageBox.Show(msg, icon, modal) | 일반 메시지 표시 |
UBiMessageBox.ShowWait(title, msg) | 대기(로딩) 메시지 표시 |
UBiMessageBox.CloseWait() | 대기 메시지 닫기 |
8.2 확장 메서드
| 메서드 | 설명 |
.Nvl() | null → 빈 문자열 변환 |
.Nvl(“default”) | null → 기본값 변환 |
.ToInt() | 문자열 → int 변환 |
ex.UBiShowException(this) | Exception을 화면에 표시 |
8.3 ResponseDB (데이터 응답 객체)
| 속성 | 설명 |
| Code | 결과 코드 (0: 성공, 그 외: 실패) |
| Message | 결과 메시지 |
9. 디자이너 설정 가이드
9.1 UBiDataAdapter 디자이너 속성 설정
Visual Studio 디자이너에서 uBiDataManager1을 선택한 후 속성 창에서 설정합니다.
- ServiceUrl → REST API 서버 주소 설정
- ServiceName → DB 서비스명 설정 (환경에 맞게 변경)
- AdapterList → 어댑터 추가/편집
각 DataAdapter에서 설정할 항목:
- NAME → 어댑터 식별 이름
- SELECT_PROCEDURE_ID → 조회 프로시저
- INSERT_PROCEDURE_ID → 등록 프로시저
- UPDATE_PROCEDURE_ID → 수정 프로시저
- DELETE_PROCEDURE_ID → 삭제 프로시저
- IsOnLoadSelect → “Y”이면 화면 로드 시 자동 조회
- LookupLayOut → 컬럼 정의 (UBiColProperty 컬렉션)
- SelectParam → 조회 파라미터 (UBiParam 컬렉션)
9.2 컬럼 추가 절차
- DataAdapter의 LookupLayOut 컬렉션 편집기를 엽니다
- Add 버튼으로
UBiColProperty를 추가합니다 - 각 속성을 설정합니다:
FIELD_NAME : DB 컬럼명 (예: ORDER_NO) TITLE : 화면 표시명 (예: 주문번호) TITLE_ID : 다국어 ID (예: ORDER_NO) DATA_TYPE : System.String | System.Int64 | System.Decimal COL_TYPE : (기본 TEXT) 또는 NUMERIC DATA_ALIGN : Near(좌측) | Center(중앙) | Far(우측) SIZE : 컬럼 너비 (기본 80) ORDER : 표시 순서 (10, 20, 30...)
9.3 파라미터 추가 절차
- DataAdapter의 SelectParam 컬렉션 편집기를 엽니다
- Add 버튼으로
UBiParam을 추가합니다
ARGUMENT_NAME : 프로시저 파라미터명 (예: A_ORDER_DATE) DATA_TYPE : VARCHAR | INT DATA_LENGTH : 문자열 길이 (예: 200) IN_OUT : IN 또는 OUT SORT_ORDER : 파라미터 순서 (1, 2, 3...) SOURCE_NAME : 바인딩 소스 이름
10. 빌드 및 배포
10.1 빌드 구성
프로젝트는 Class Library(DLL) 형태로 빌드됩니다.
| 구성 | 출력 경로 | 최적화 |
| Debug | bin\Debug\ | 비활성화 |
| Release | bin\Release\ | 활성화 |
10.2 PostBuild 이벤트
빌드 완료 후 자동으로 afterbuild 스크립트가 실행됩니다.
$(SolutionDir)\afterbuild $(SolutionDir) $(ProjectDir) $(TargetFileName)
이 스크립트는 빌드된 DLL을 실행 환경의 dll 폴더로 복사합니다.
10.3 프로젝트 참조
새 프로젝트 생성 시 다음 참조가 필요합니다:
- POPUP_COMMON — 공통 팝업 프로젝트
- UXHelper — UX 도우미 유틸리티
- UBi 프레임워크 DLL —
UBi3FrameWork/FrameWorkReference/경로의 DLL 파일들 - DevExpress v20.1 — UI 컨트롤 라이브러리
11. 코딩 컨벤션
11.1 네임스페이스
모든 업무화면은 UX 네임스페이스를 사용합니다.
namespace UX { public partial class UBi_FORM_ORD001 : BaseModule { } }
11.2 코드 작성 규칙
- try-catch-finally 패턴 필수: 조회/저장 등 DB 작업 시 항상 사용
- UBiMessageBox.ShowWait / CloseWait 쌍: 장시간 작업 시 반드시 쌍으로 사용
- base 호출:
override메서드에서 반드시base.메서드명(f)먼저 호출 - 이벤트 등록:
Form_Load에서 그리드 이벤트를 람다로 등록 - 주석: 한글 주석으로 비즈니스 로직 설명 기재
11.3 명명 규칙
| 대상 | 규칙 | 예시 |
| 프로젝트명 | UBi_FORM_{업무코드} | UBi_FORM_ORD001 |
| 클래스명 | 프로젝트명과 동일 | UBi_FORM_ORD001 |
| DataAdapter NAME | 대문자 영어 | TEST, ORDER, ITEM |
| 프로시저 ID | PKG_{업무}${동작} | PKG_ORD$GET_LIST |
| 컬럼 FIELD_NAME | 대문자 스네이크 | ORDER_NO, CUST_NAME |
12. 자주 묻는 질문 (FAQ)
Q1. 화면 로드 시 자동 조회가 안 됩니다
→ DataAdapter의 IsOnLoadSelect 속성이 “Y”로 설정되어 있는지 확인하세요. 또한 Form_Load에서 uBiDataManager1.Init()이 호출되고 있는지 확인하세요.
Q2. 저장 후 ResponseDB.Code가 0이 아닙니다
→ DB 프로시저의 N_RETURN OUT 파라미터 값을 확인하세요. 프로시저 내부에서 오류 발생 시 0이 아닌 값을 반환합니다. V_RETURN에 상세 오류 메시지가 포함됩니다.
Q3. 그리드 컬럼이 표시되지 않습니다
→ DataAdapter의 LookupLayOut 컬렉션에 컬럼 정의가 추가되어 있는지 확인하세요. ORDER 값이 올바르게 설정되어야 합니다.
Q4. 빌드 후 화면이 반영되지 않습니다
→ PostBuild 이벤트(afterbuild)가 정상 실행되었는지 확인하세요. 실행 환경의 dll 폴더에 최신 DLL이 복사되었는지 점검합니다.
Q5. REST API 연결이 실패합니다
→ uBiDataManager1의 ServiceUrl, ServiceName, ServiceUserId, ServicePassword 속성이 올바른지 확인하세요. 개발 환경에 맞게 설정을 변경해야 합니다.
13. 참고 링크
- DevExpress v20.1 문서: DevExpress WinForms Documentation
- .NET Framework 4.7.2: Microsoft .NET Framework
이 문서는 UBi_FORM_SEC 템플릿 프로젝트를 기반으로 작성되었습니다.
최종 수정: 2026-03-21
