====== UBi WinForms 프레임워크 개발 가이드 ====== //작성일: 2026-03-21 | 대상: VS 2019 + .NET Framework 4.7.2 + DevExpress// ----- ===== 목차 ===== - [[#개요|개요]] - [[#솔루션구조|솔루션 구조]] - [[#기본화면개발|기본 화면 개발]] - [[#컨트롤목록|컨트롤 목록]] - [[#데이터관리|데이터 관리 (UBiDataManager)]] - [[#버튼타입|버튼 타입 및 커맨드]] - [[#다국어|다국어 지원]] - [[#권한관리|권한 관리]] - [[#메시지박스|메시지 박스 / 팝업]] - [[#주의사항|개발 주의사항]] ----- ===== 1. 개요 ===== UBi 프레임워크는 **DevExpress WinForms** 기반의 사내 UI 프레임워크입니다. 화면 개발자는 직접 데이터 바인딩, 다국어, 권한, 레이아웃 관리를 신경 쓸 필요 없이 정해진 **Base 클래스와 컨트롤**을 사용하여 업무 화면을 빠르게 개발할 수 있습니다. ^ 항목 ^ 내용 ^ | IDE | Visual Studio 2019 (16.11.x) | | Framework | .NET Framework 4.7.2 | | UI Library | DevExpress WinForms | | SVN | AnkhSVN2019 | | 언어 | C# | ----- ===== 2. 솔루션 구조 ===== UBiDLL.sln ├── 10.Standard/ ← 공통 라이브러리 (.NET Standard) │ ├── UBi/ ← 핵심 유틸리티 (Crypto, Log, DataConverter) │ ├── UBi.IO/ ← 파일 I/O │ ├── UBi.Net/ ← 네트워크 공통 모델 │ ├── UBi.Net.RestfulClient/ ← REST API 클라이언트 │ ├── UBi.Net.Sockets/ ← 소켓 통신 │ ├── UBi.Net.Server/ ← 서버 처리 │ ├── UBi.Platform/ ← 플랫폼 공통 (설정, 사용자정보, DB요청) │ ├── UBi.Database/ ← DB 추상화 인터페이스 │ ├── UBi.Database.MySql/ ← MySQL │ ├── UBi.Database.Oracle/ ← Oracle │ ├── UBi.Database.SQLServer/← SQL Server │ └── UBi.DataBase.PostgreSQL/← PostgreSQL │ └── 30.WinForm/ ← WinForms UI 레이어 ├── UBi.Platform.Images/ ← 이미지 / 아이콘 리소스 ├── UBi.WinForm/ ← WinForms 공통 유틸 └── UBi.WinForm.Controls/ ← 커스텀 컨트롤 (개발 핵심) ==== 화면 개발 시 참조해야 할 프로젝트 ==== ^ 프로젝트 ^ 역할 ^ 필수 여부 ^ | UBi.WinForm.Controls | 커스텀 컨트롤 및 Base 클래스 | ✅ 필수 | | UBi.Platform | 설정, 사용자정보, DB요청 | ✅ 필수 | | UBi.Platform.Images | 아이콘/이미지 리소스 | ✅ 필수 | | UBi.Net | 서비스 통신 모델 | ✅ 필수 | ----- ===== 3. 기본 화면 개발 ===== ==== 3.1 화면 유형 선택 ==== UBi 프레임워크에는 세 가지 기본 화면 유형이 있습니다. ^ 클래스 ^ 용도 ^ 상속 ^ | BaseModule | 일반 업무 화면 (MDI 탭 내부) | XtraUserControl | | BaseForm | 팝업 / 독립 다이얼로그 화면 | XtraForm | | UBiMdiForm | MDI 메인 컨테이너 폼 | XtraForm | ==== 3.2 BaseModule - 업무 화면 기본 구조 ==== 업무 화면은 반드시 **BaseModule** 을 상속받아 개발합니다. using UBi.WinForm.Controls; namespace MyApp { public partial class FrmSampleModule : BaseModule { public FrmSampleModule() { InitializeComponent(); } // 화면이 완전히 로드된 후 실행됨 (Application.Idle 이후) public override void OnLoaded(object sender, EventArgs e) { base.OnLoaded(sender, e); // 초기 조회 등 로드 후 처리 DoSearch(); } private void DoSearch() { // DataBase (UBiDataManager) 를 통해 조회 DataBase?.Fill(); } // 저장 버튼 클릭 시 private void btnSave_UBiCheckValidate(object sender, EventArgButtonClick e) { if (!e.isPass) return; DataBase?.Update(); } } } ==== 3.3 BaseModule 주요 속성 ==== ^ 속성 ^ 타입 ^ 설명 ^ | DataBase | UBiDataManager | 데이터 CRUD 처리 컴포넌트 | | Param | Dictionary | 화면 호출 시 전달받은 파라미터 | | EditMode | UBiEditModeEnum | 현재 화면 편집 모드 | | IsLoaded | bool | 화면 최초 로딩 완료 여부 | | IsSearched | bool | 조회를 수행한 적 있는지 여부 | | MenuSeq | string | 현재 메뉴 SEQ | | ModuleCode | string | 현재 모듈 코드 | | Authority | UBiFormAuthority | 화면 권한 정보 | | DBParam | Dictionary | DB 쿼리용 파라미터 | ==== 3.4 BaseForm - 팝업 화면 ==== 팝업 화면은 **BaseForm** 을 상속받아 개발합니다. public partial class FrmPopupSample : BaseForm { public FrmPopupSample() { InitializeComponent(); } // 팝업에서 결과 데이터 반환 시 private void btnOk_Click(object sender, EventArgs e) { // PopupReturnData 에 반환값 설정 this.PopupReturnData = gridView1.GetFocusedDataRow(); this.DialogResult = DialogResult.OK; this.Close(); } } ==== 3.5 UBiMdiForm - MDI 컨테이너 ==== BaseModule 을 MDI 탭에 올릴 때 사용합니다. // BaseModule을 MDI로 열기 var module = new FrmSampleModule(); var mdiForm = new UBiMdiForm(module); mdiForm.MdiParent = this; mdiForm.Show(); ==== 3.6 화면 로딩 순서 ==== [생성자] InitializeComponent() ↓ [OnLoad] BaseProcess 초기화, 언어 초기화 ↓ [Application.Idle] OnLoaded() 호출 ↓ [OnLoaded] LoadGridViewLayout(), 권한 적용 ↓ [개발자 Override] OnLoaded() 에서 초기 조회 수행 > ⚠️ **주의**: 초기 조회는 반드시 **OnLoaded** 에서 수행하세요. > 생성자나 OnLoad 에서 데이터를 조회하면 컨트롤 초기화 전에 실행될 수 있습니다. ----- ===== 4. 컨트롤 목록 ===== ==== 4.1 입력 컨트롤 ==== ^ 컨트롤 ^ 클래스명 ^ 용도 ^ | 텍스트 입력 | UBiTextEdit | 일반 텍스트 입력 | | 버튼 텍스트 입력 | UBiButtonText | 버튼 텍스트 입력 | | 메모 입력 | UBiMemoEdit | 여러 줄 텍스트 입력 | | 날짜 입력 | UBiDateEdit | 날짜 선택 입력 | | 날짜 범위 입력 | UBiFromToDateEdit | 시작일 ~ 종료일 입력 | | 숫자 입력 | UBiSpinEdit | 숫자 스핀 입력 | | 콤보박스 | UBiComboBoxEdit | 드롭다운 선택 | | 이미지 콤보박스 | UBiImageComboBoxEdit | 이미지 포함 드롭다운 | | 체크박스 | UBiCheckEdit | 체크 입력 | | 라디오 버튼 | UBiRadioGroup | 라디오 그룹 선택 | | 링크 | UBiHyperLinkEdit | 하이퍼링크 표시 | | 이미지 | UBiPictureEdit | 이미지 표시/업로드 | ==== 4.2 조회 컨트롤 ==== ^ 컨트롤 ^ 클래스명 ^ 용도 ^ | 검색 드롭다운 | UBiSearchLookUpEdit | 검색 가능한 드롭다운 선택 | | 그리드 드롭다운 | UBiGridLookUpEdit | 그리드 형태의 드롭다운 선택 | ==== 4.3 그리드 컨트롤 ==== ^ 컨트롤 ^ 클래스명 ^ 용도 ^ | 기본 그리드 뷰 | UBiGridView | 표준 행/열 그리드 | | 밴드 그리드 뷰 | UBiBandedGridView | 열 밴드(그룹헤더) 지원 그리드 | | 고급 밴드 그리드 | UBiAdvBandedGridView | 고급 밴드 레이아웃 그리드 | | 그리드 컨트롤 | UBiGridControl | GridView의 컨테이너 | | 트리 리스트 | UBiTreeList | 계층형 트리 구조 데이터 | ==== 4.4 버튼 컨트롤 ==== ^ 컨트롤 ^ 클래스명 ^ 용도 ^ | 기본 버튼 | UBiSimpleButton | CRUD 및 사용자 정의 액션 버튼 | | 바 버튼 | UBiBarButtonItem | 툴바 버튼 | ==== 4.5 레이아웃 컨트롤 ==== ^ 컨트롤 ^ 클래스명 ^ 용도 ^ | 레이아웃 컨트롤 | UBiLayoutControl | 컨트롤 배치 레이아웃 컨테이너 | | 레이아웃 그룹 | UBiLayoutControlGroup | 레이아웃 그룹 | | 탭 그룹 | UBiTabbedControlGroup | 탭 형태의 레이아웃 그룹 | | 레이아웃 아이템 | UBiLayoutControlItem | 레이아웃 내 개별 아이템 | | 둥근 패널 | UBiRoundPanel | 둥근 모서리 패널 | ==== 4.6 기타 컨트롤 ==== ^ 컨트롤 ^ 클래스명 ^ 용도 ^ | 레이블 | UBiLabelControl | 텍스트 표시 레이블 | | 다이어그램 | UBiDiagramControl | 다이어그램 표시 | | 파일 매니저 | UBiFileManager | 파일 첨부/관리 | | 사진 뷰어 | UBiPhotoViewer | 이미지 미리보기 | | 즐겨찾기 컨트롤 | UBiFavoritControl | 즐겨찾기 관리 | ==== 4.7 공통 IUBiControl 인터페이스 속성 ==== 모든 UBi 입력 컨트롤은 **IUBiControl** 인터페이스를 구현합니다. ^ 속성 ^ 타입 ^ 설명 ^ | UBiFieldName | string | DB 컬럼과 자동 바인딩될 필드명 | | EditValue | object | 현재 입력값 | | UBiFontSize | int | 기본 폰트 크기 | | UBiRequirement | bool | 필수 입력 여부 | | UBiValidationGroup | UBiValidationGroup | 유효성 검사 그룹 | | UBiValidationAction | UBiValidationAction | 유효성 검사 액션 | | UBiCompareWith | object | 비교 대상 컨트롤 | | UBiReadOnlyFree | bool | ReadOnly 강제 해제 여부 | | Tag1 / Tag2 / Tag3 | object | 확장 태그 (자유 사용) | ----- ===== 5. 데이터 관리 (UBiDataManager) ===== ==== 5.1 개요 ==== **UBiDataManager** 는 화면과 DB 사이의 데이터 흐름을 담당하는 핵심 컴포넌트입니다. 디자인 타임에 컴포넌트 트레이에 추가하고, BaseModule.DataBase 속성에 연결하여 사용합니다. // Designer에서 설정되는 항목들 ubiDataManager1.ServiceUrl = "http://server:port"; ubiDataManager1.ServiceName = "ServiceName"; ubiDataManager1.ServiceUserId = "userId"; ubiDataManager1.ServicePassword = "password"; ==== 5.2 주요 속성 ==== ^ 속성 ^ 타입 ^ 설명 ^ | ServiceUrl | string | 서비스 URL | | ServiceName | string | 서비스명 | | ServiceUserId | string | 서비스 접속 ID | | AdapterList | List | 데이터 어댑터 목록 | | IsFullLoad | bool | 전체 데이터 로드 여부 | | IsInit | bool | 초기화 여부 | | restDb | RequestDB | REST DB 요청 객체 | ==== 5.3 데이터 조회 ==== // 전체 조회 DataBase.Fill(); // 파라미터 지정 후 조회 DataBase.SetParam("A_USER_ID", userId); DataBase.SetParam("A_DEPT_CD", deptCode); DataBase.Fill(); ==== 5.4 데이터 저장/삭제 ==== // 변경된 데이터 저장 (Insert/Update 처리) DataBase.Update(); // 선택된 행 삭제 DataBase.Delete(); ==== 5.5 이벤트 ==== ^ 이벤트 ^ EventArgs 타입 ^ 설명 ^ | EventDataFillComplete | DataFillCompletArg | 데이터 조회 완료 | | EventRowFocusChanged | DataRowForcusArg | 포커스된 행 변경 | | EventRowValueChanged | DataRowChangeArg | 셀 값 변경 | | EventBeginDataRowDeleting | BeginDataRowDeletingArg | 행 삭제 시작 (Cancel 가능) | | EventBeginUpdate | BeginUpdateArg | 저장 시작 (Cancel 가능) | // 조회 완료 후 처리 예시 private void DataBase_EventDataFillComplete(object sender, DataFillCompletArg e) { // e.Value: 조회된 DataTable lblCount.Text = $"총 {e.Value.Rows.Count} 건"; } // 행 삭제 취소 예시 private void DataBase_EventBeginDataRowDeleting(object sender, BeginDataRowDeletingArg e) { if (e.row["STATUS"].ToString() == "Y") { e.Cancel = true; // 삭제 취소 UBiMessageBox.Show("사용중인 데이터는 삭제할 수 없습니다."); } } ----- ===== 6. 버튼 타입 및 커맨드 ===== ==== 6.1 UBiButtonTypeEnum ==== **UBiSimpleButton** 의 ButtonType 속성에 설정하면 자동으로 아이콘이 적용됩니다. ^ ButtonType ^ 설명 ^ 단축키 예시 ^ | None | 정의 없음 | | | Init | 초기화 | F2 | | Add | 추가 | Insert | | Remove | 제거 | Delete | | Save | 저장 | F9 | | Delete | 삭제 | F8 | | Cancel | 취소 | Esc | | Close | 닫기 | Alt+F4 | | Export | 내보내기 | | | Import | 가져오기 | | | Ok | 확인 | Enter | | Print | 인쇄 | Ctrl+P | | Preview | 미리보기 | | | Setting | 설정 | | | User | 사용자 정의 | | | View | 보기 | | | Copy | 복사 | Ctrl+C | | New | 새 입력 | | | Forward | 앞으로 | | | Backward | 뒤로 | | ==== 6.2 UBiCommandType (CRUD) ==== ^ CommandType ^ 값 ^ 설명 ^ | None | 0 | 미정의 | | Create | 1 | 신규 추가 | | Read | 2 | 조회 | | Update | 3 | 수정 | | Delete | 4 | 삭제 | ==== 6.3 버튼 사용 예시 ==== // 저장 버튼 - Validation 통과 후 실행 private void btnSave_UBiCheckValidate(object sender, EventArgButtonClick e) { if (!e.isPass) { // 유효성 검사 실패 - e.message에 실패 이유 UBiMessageBox.Show(e.message); return; } DataBase?.Update(); } > 💡 **팁**: UBiSimpleButton 의 기본 이벤트는 **UBiCheckValidate** 입니다. > UBiRequirement, UBiValidationGroup 설정 시 자동으로 유효성 검사 후 이벤트가 발생합니다. ----- ===== 7. 다국어 지원 ===== ==== 7.1 개요 ==== UBi 프레임워크는 **다국어(Glossary)** 를 기본 지원합니다. 컨트롤에 **UBiGlossaryCode** 를 설정하면 런타임에 자동으로 번역됩니다. ==== 7.2 언어 관련 클래스 ==== ^ 클래스/메서드 ^ 설명 ^ | KoreanGridLocalizer | DevExpress 그리드 메뉴 한국어화 | | KoreanLocalizer | DevExpress UI 요소 한국어화 | | IUBiLanguageControl | 다국어 컨트롤 인터페이스 | | GetGlossary() | 현재 언어로 번역된 텍스트 반환 | | UBiLanguageTransTo() | 전체 컨트롤 언어 일괄 변환 | ==== 7.3 한국어 그리드 메뉴 적용 ==== // BaseModule.OnLoad 에서 자동 적용됨 if (PlatformGlobal.Settings.ToolTipLanguage == "ko") { GridLocalizer.Active = new KoreanGridLocalizer(); } ==== 7.4 다국어 코드 사용 예시 ==== // 문자열을 현재 언어로 번역 string translatedText = "SAVE".GetGlossary(); // 컨트롤 전체 언어 변환 this.UBiLanguageTransTo(); ----- ===== 8. 권한 관리 ===== ==== 8.1 UBiFormAuthority ==== 화면별 CRUD 권한을 관리합니다. ^ 속성 ^ 타입 ^ 설명 ^ | Add | int | 추가 권한 (1=허용, 0=불가) | | Save | int | 저장 권한 | | Delete | int | 삭제 권한 | | Print | int | 인쇄 권한 | | Export | int | 내보내기 권한 | ==== 8.2 권한 적용 방식 ==== // UBiMdiForm 생성 시 자동으로 버튼 권한 적용 public UBiMdiForm(BaseModule module, string path = "") { UBiFormAuthority = ((IUBiFormAuthority)module).Authority; baseModule = module; baseModule.InitAuthority(UBiFormAuthority); SetButtonAuthority(); // 버튼 Enabled 자동 설정 } // 수동 권한 적용 public void InitAuthority(UBiFormAuthority au) { Authority = au; // LayoutControl 내 IUBiAuthority 컨트롤에 일괄 적용 foreach (LayoutControl ctl in this.Controls.OfType()) foreach (IUBiAuthority auCtl in ctl.Controls.OfType()) auCtl.InitAuthority(au); } ==== 8.3 UX 이벤트 로그 ==== // 사용자 행동 로그 기록 this.UXEventLogWrite("조회버튼 클릭"); this.UXEventLogWrite("저장완료"); ----- ===== 9. 메시지 박스 / 팝업 ===== ==== 9.1 UBiMessageBox 사용 ==== ^ 메서드 ^ 설명 ^ | UBiMessageBox.Show(msg) | 일반 메시지 표시 | | UBiMessageBox.ShowError(msg) | 에러 메시지 표시 | | UBiMessageBox.ShowWarning(msg) | 경고 메시지 표시 | | UBiMessageBox.ShowWait(title,msg) | 로딩 대기 화면 표시 | | UBiMessageBox.CloseWait() | 로딩 대기 화면 닫기 | // 일반 메시지 UBiMessageBox.Show("저장이 완료되었습니다."); // 로딩 표시 UBiMessageBox.ShowWait("Please Wait", "Loading ..."); try { // 작업 수행 DataBase.Fill(); } finally { UBiMessageBox.CloseWait(); } ==== 9.2 UBiQuestionBox ==== // 확인/취소 다이얼로그 var result = UBiQuestionBox.Show("삭제하시겠습니까?"); if (result == DialogResult.Yes) { DataBase.Delete(); } ==== 9.3 UBiSplashScreen ==== // 앱 시작 시 스플래시 화면 UBiSplashScreen.Show(); // 초기화 작업... UBiSplashScreen.Close(); ----- ===== 10. 개발 주의사항 ===== ==== 10.1 화면 개발 체크리스트 ==== - [ ] **BaseModule** 상속 여부 확인 - [ ] **UBiDataManager** 컴포넌트 트레이에 추가 및 DataBase 속성 연결 - [ ] 초기 조회는 **OnLoaded** 에서 수행 - [ ] 저장/삭제 전 **UBiCheckValidate** 이벤트 활용 - [ ] UBiFieldName 과 DB 컬럼명 일치 여부 확인 - [ ] **KoreanGridLocalizer** 적용 여부 확인 (한국어 환경) - [ ] 권한 적용 필요 시 **UBiFormAuthority** 설정 ==== 10.2 자주 하는 실수 ==== ^ 실수 ^ 올바른 방법 ^ | 생성자에서 데이터 조회 | OnLoaded() 오버라이드 후 조회 | | 직접 MessageBox.Show 사용 | UBiMessageBox.Show() 사용 | | GridView 직접 사용 | UBiGridView / UBiGridControl 사용 | | 다국어 미적용 하드코딩 문자열 | GetGlossary() 확장메서드 사용 | | 권한 없이 버튼 활성화 | UBiFormAuthority 통해 권한 제어 | ==== 10.3 DPI 스케일링 ==== // BaseModule.OnLoad 에서 자동 적용됨 this.AutoScaleMode = AutoScaleMode.Dpi; this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); this.DoubleBuffered = true; > ⚠️ 고해상도(4K, 2K) 모니터 사용 환경에서는 **app.manifest** 에 DPI 인식 설정을 추가해야 합니다. ==== 10.4 디자인 타임 서버 설정 ==== 개발 시 VS Designer 에서 데이터를 미리 보려면 로컬 서버가 실행 중이어야 합니다. 환경변수 UBI3_SERVER = {서버 실행파일 경로} 예: UBI3_SERVER=D:\UBi3Server\ // 디자인 타임에 서버 자동 기동 DataBase.startLocalServer(); ----- //문의: 개발팀 polonel9@gmail.com | 최종수정: 2026-03-21//