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