반응형

WANIGrid Control에 마우스 휠 처리를 추가했다.

마우스 휠을 움직이면 데이터의 행(Row)를 100씩 이동하도록 했고, Control 키를 누른 상태에서 마우스 휠을 움직이면 좌우 방향으로 100씩 움직이도록 보완을 했다.

마우스 휠 부분은 VScrollBar와 HScrollBar를 움직였을 때와 같이 처리 되도록 했다.

WANIGrid Control의 헤더 속성 중에 IsRowHeader가 true인 경우와 아닌 경우의 차이는 고정 컬럼 여부이다.

    /// <summary>
    /// WANIGrid MouseWheel Event
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void PicGrid_MouseWheel(object sender, MouseEventArgs e)
    {
        if (ModifierKeys == Keys.Control)   //Control Key를 눌렀을 떄, HScrollBar를 움직인 것과 동일
        {
            if (e.Delta / 120 > 0)
            {
                if (grid.StartColumnPosition - 100 < 0) grid.StartColumnPosition = 0;
                else grid.StartColumnPosition -= 100;
            }
            else
            {
                if (grid.StartColumnPosition + 100 < hScrollBar.Maximum)
                {
                    grid.StartColumnPosition += 100;                        
                }
                else 
                {
                    grid.StartColumnPosition = hScrollBar.Maximum;
                }
            }
            IsMouseWheel = true;
        }
        else //VScrollBar를 움직인 것과 동일
        {
            if (e.Delta / 120 > 0)
            {
                if (grid.StartRowPosition - 100 < 0) grid.StartRowPosition = 0;
                else grid.StartRowPosition -= 100;
            }
            else
            {
                if (grid.StartRowPosition + 100 < vScrollBar.Maximum) grid.StartRowPosition += 100;
            }
            IsMouseWheel = false;
        }
        picGrid.Invalidate();
    }

[그림 1] IsRowHeader 가 true인 경우 (Column01, Column02 가 true임)

첨부된 WANIGridExample.cs 파일에서 WANIGrid를 사용하는 방법을 참조하기 바람.

WANIGrid.dll
0.05MB
WANIGridControlExample.zip
0.21MB

반응형

'WinForm > WANIGrid 컨트롤 공개' 카테고리의 다른 글

WANIGrid Control 개선  (0) 2021.04.10
WANIGrid Control 사용법 2  (0) 2020.05.14
WANIGrid Control 사용법 1  (1) 2020.04.30
반응형

기존에 만들었던 WANIGrid의 전체적인 모습과 구조를 대대적으로 바꾸었다.

WANIGrid 스크롤 영역에 대한 처리와 전체 적인 모습들을 좀 더 개선하고자 했다.

추가로 헤더 그룹을 구성할 수 있도록 API를 추가했다.

WANIGrid를 사용하기 위해서는 프로그램 단에서 WANIGrid를 초기화 하는 작업이 필요하다.

초기화 메소드를 하나 만들어서 WANIGrid에 필요한 설정을 하도록 한다.

 

HeaderColumn의 ColumnId는 DataTable의 Column과 대응된다.

waniGridControl1.DataSource 값으로 DataTable을 할당하게 되면 ColumnId의 값과  동일한 DataTable의 필드  값이 WANIGrid 에 나타나게 된다.

 

현재는 셀 선택 시 편집 모드는 TextBox 형태만 지원하고 있다. 향 후 CheckBox, ComboBox, DatePicker 등을 지원할 예정이다.

private void InitializeGrid()
{
    //첫번째 헤드그룹 지정
    List<HeaderGroup> headerGroups0 = new List<HeaderGroup>()
    {
        new HeaderGroup() { StartColumnId = "Col02", NumberOfColumns = 4, TitleText = "Test Top 01" }
    };

    //두번째 헤드그룹 지정
    List<HeaderGroup> headerGroups = new List<HeaderGroup>()
    {
        new HeaderGroup() { StartColumnId = "Col02", NumberOfColumns = 2, TitleText = "Test 01" },
        new HeaderGroup() { StartColumnId = "Col04", NumberOfColumns = 2, TitleText = "Test 02" }
    };
    //헤드 지정
    List<HeaderColumn> headerCols = new List<HeaderColumn>()
    {
        new HeaderColumn() { ColumnId = "Col01", HeaderTitle = "Column 01", IsRowHeader = false, IsEdit = true, EditorType = EditControlType.TextBox, HeaderTitleAlign = HorizontalAlignment.Center, TextAlign = HorizontalAlignment.Left, Visible = true, Width = 100  },
        new HeaderColumn() { ColumnId = "Col02", HeaderTitle = "Column 02", IsRowHeader = false, IsEdit = true, EditorType = EditControlType.TextBox, HeaderTitleAlign = HorizontalAlignment.Center, TextAlign = HorizontalAlignment.Center, Visible = true, Width = 100  },
        new HeaderColumn() { ColumnId = "Col03", HeaderTitle = "Column 03", IsRowHeader = false, IsEdit = true, EditorType = EditControlType.TextBox, HeaderTitleAlign = HorizontalAlignment.Center, TextAlign = HorizontalAlignment.Left, Visible = true, Width = 200  },
        new HeaderColumn() { ColumnId = "Col04", HeaderTitle = "Column 04", IsRowHeader = false, IsEdit = true, EditorType = EditControlType.TextBox, HeaderTitleAlign = HorizontalAlignment.Center, TextAlign = HorizontalAlignment.Left, Visible = true, Width = 100  },
        new HeaderColumn() { ColumnId = "Col05", HeaderTitle = "Column 05", IsRowHeader = false, IsEdit = true, EditorType = EditControlType.TextBox, HeaderTitleAlign = HorizontalAlignment.Center, TextAlign = HorizontalAlignment.Left, Visible = true, Width = 200  },
        new HeaderColumn() { ColumnId = "Col06", HeaderTitle = "Column 06", IsRowHeader = false, IsEdit = true, EditorType = EditControlType.TextBox, HeaderTitleAlign = HorizontalAlignment.Center, TextAlign = HorizontalAlignment.Left, Visible = true, Width = 150  },
        new HeaderColumn() { ColumnId = "Col07", HeaderTitle = "Column 07", IsRowHeader = false, IsEdit = true, EditorType = EditControlType.TextBox, HeaderTitleAlign = HorizontalAlignment.Center, TextAlign = HorizontalAlignment.Left, Visible = true, Width = 200  }
    };

    //Header 정보 추가
    TopHeader header = new TopHeader(headerCols);
    //최상위 헤더 그룹 설정
    header.SetGroupHeaders(0, headerGroups0);
    //상위 헤더 그룹 설정
    header.SetGroupHeaders(headerGroups);
    //Header 정보 설정
    waniGridControl1.SetHeader(header);    
}

 

아래의 첨부 파일의 소스를 실행한 결과 화면

[그림 3-1] WANIGrid Control 사용 예제 1 - 셀 편집 시 화면
[그림 3-2] WANIGrid Control 사용 예제 2 - 한 개의 행 선택 시
[그림 3-2] WANIGrid Control 사용 예제 3 - 여러 개의 행 선택 시

 

[그림 3-2] WANIGrid Control 사용 예제 4 - 한 개의 컬럼 선택 시
[그림 3-2] WANIGrid Control 사용 예제 5 - 여러 개의 컬럼 선택 시

아래의 첨부한 소스를 참조

 

WANIGridControlExample.zip
0.21MB
WANIGrid.dll
0.05MB
WANIGrid_속성정리.pdf
0.09MB

반응형
반응형

jQuery UI의 Datepicker를 아래의 이미지와 같이 설정한다.

[그림 1] 구현 하고자 하는 Datepicker 모습

 

$('#workMfgDate').datepicker({

    dateFormat: "yy.mm.dd",

    monthNames: [ "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월" ],
    monthNamesShort: [ "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월" ],
    dayNamesMin: [ "일", "월", "화", "수", "목", "금", "토" ],
    firstDay: 1, 
    changeYear: true,
    changeMonth:true,
    showButtonPanel: true,
    gotoCurrent: true,
    closeText: "Clear",
    currentText: "오늘",
    showOn: "both",

    buttonImage: "./images/icon/monthlycalendar.png",

    buttonImageOnly: true

});

 

monthNames와 monthNamesShort 에 한글로 1~12월 까지의 명칭을 표기하도록 설정한다.
firstDay가 1이면 월요일, 0 이면  일요일 시작요일이 된다.
changeYear값이 true 이면 년을 선택할 수 있는 콤보박스가 제공된다.
changeMonth값이 true 이면 월을 선택할 수 있는 콤보박스가 제공된다.
showButtonPanel 값을 true로 하면 달력의 아래 부분에 Today/Close 버튼이 나타난다.
closeText는 Close버튼의 명칭을 말하며, 버튼의 명칭을 Clear로 변경하고 클릭 시 선택한 날짜 값을 지우고 달력을 숨기도록 바인딩 할 예정이다.
currentText는 Today버튼의 명칭을 오늘로 바꾸고 오늘 일자를 설정하고 달력을 숨기도록 바인딩 할 예정이다.
showOn 값을 both로 하게 되면 input 과 Image button 둘 다 사용할 수 있으며, button으로 설정할 경우 Image button을 클릭했을 때만 달력이 나타나게 된다.

buttonImage는 input 옆에 생기는 버튼에 아이콘을 추가할 수 있다.
buttonImageOnly 값이 true이면 버튼의 테두리는 제공되지 않고 이미지만 표시되며, false일 경우 버튼 위에 이미지가 있게 된다.

 

html 문서의 input type 설정 부분

<input type="text" id="workMfgDate" name="workMfgDate" readonly style="width:80px;text-align:center;">

 

jQuery UI Datepicker에서 showButtonPanel 값을 true로 설정을 했지만, Today 버튼을 클릭해도 아무런 반응이 없다.

따라서 오늘 날짜를 적용하고 창을 닫는 동작을 할 수 있도록 jQuery 바인딩 코드를 작성해야 한다.

 

오늘(Today) 버튼 클릭 시 오늘 날짜를 적용하고 창을 닫는다.

$('button.ui-datepicker-current').live('click', function() {

    $.datepicker._curInst.input.datepicker('setDate', new Date()).datepicker('hide').blur();

});

 

Close(Clear) 버튼 클릭 시 값을 지우고 창을 닫는다.

$('button.ui-datepicker-close').live('click', function() {

    $.datepicker._curInst.input.datepicker('setDate', '').datepicker('hide').blur();

});

반응형
반응형

기다리던 애플 워치 SE 개봉기.
결혼 20주년 기념으로 부부가 함께 건강을 위해 구입한 애플 워치 SE.
같은 날 애플스토어에서 주문을 했지만 각각 시간이 달라서 인지 와이프는 지난 주에 도착했지만, 난 오늘(11/30)에야 도착했다.
오래 기다린 만큼 반가웠고, 언박싱하는 기분을 느껴보며 찍은 사진이다.

겉 포장지 뚜껑을 개봉한 모습이다. 환경을 생각해서인지 종이 박스 내부의 충격 방지용으로도 같은 종이 박스의 재질로 구성되어져 있다.
부피만 큰 뾱뾱이 보다는 이게 훨씬 나아 보인다.


내부의 검은색 포장지를 벗긴 모습이다. 테이프나 풀로 마감처리가 된 것이 아니라 종이 박스의 동그란 부위를 접어서 자연스럽게 열 수 있도록 디자인되어져 있다.
포장에도 상당한 공을 들인 느낌이 든다.
포장은 심플하면서도 깔끔하고 굉장히 실용적으로 만들어 진 것 같다. 내용물을 빼고 상자를 원형과 큰 차이가 없도록 다시 포장해서 보관할 수 있도록 여러모로 배려를 한 듯 싶다.
내부에는 회색의 2개 상자가 있으며, 애플 워치 SE 본체/충전기 박스와 시계 줄 박스로 구성되어져 있다.


상자의 겉 포장지와 시계 줄 박스, 애플 워치 SE 본체 박스로 아주 단촐하게 구성되어져 있다.


시계 줄은 긴줄/짧은 줄 2개가 제공되고 있으며 자신의 손목에 맞는 줄을 하나를 선택해서 시계에 장착하면 된다.
난 긴줄을 선택해서 시계 본체에 장착했다.


시계 줄을 장착하고 시계 전원을 넣어서 찍어 본 사진이다.
애플 워치 SE 언박싱은 아주 재미있었고, 포장 하나 하나를 벗기면서 역시 애플이다라는 생각을 버릴 수 없었다.
애플 워치를 사용하면서 느끼는 소소한 부분들을 기회가 있을 때 마다 포스팅을 할 생각이다.













반응형

'IT제품' 카테고리의 다른 글

블루투스 스피커 만들기 (2/2)  (0) 2022.04.30
블루투스 스피커 만들기 (1/2)  (0) 2022.04.30
굿노트용 2022년 Calendar 일정관리  (0) 2021.11.27
아이폰12 프로 개봉기  (0) 2020.11.12
반응형

애플 스토어에서 아이폰12 프로를 주문하고 1주일을 기다린 끝에 폰을 받았다.
기존의 아이폰7 32GB를 4년간 잘 이용해 왔었고, 12가 나오기만을 기다리고 있었기에 10월 31일에 바로 주문을 했었다.
내 손에 쥐어지기 까지 2주 정도를 예상했는데 10일 만에 내품으로 왔다.
iPhone 12 Pro 128GB 퍼시픽 블루를 선택했고, 첫 박스의 모습은 단촐했다는 느낌이었다.
충전기와 이어폰이 없는 상태라고는 하지만 기존의 박스 모습과는 사뭇 많이 다른 느낌이었다.


뚜껑을 열어서 보자 내부는 더 단촐(?) 했다고나 할까?
설명서와 충전선, iPhone 12 Pro 본체로 구성된 미니멀리즘이 뭔지를 확실히 보여주는 듯 하다.
처음에는 이게 135만원 맞아? 너무 단촐한거 아냐? 하는 생각이 들었다.


웬지 사기당한(?) 느낌 내지 이건 뭐지 하는 생각으로 내부 구성품과 폰을 몇 번이고 확인했다.
애플의 주장을 그대로 믿고 받아들이기에는 뭔가 석연치 않지만, 일단 폰을 들어 자세히 살피며 손으로 쥐어봤을 때 느낌이 너무 좋았다.
iPhone 5때와 동일한 디자인의 각진 모습과 곡선을 보면서 역시 iPhone 이라는 생각이 들었다.
내 개인적으로도 iPhone 5때의 디자인을 좋았했던터라 이번 iPhone 12 디자인 또한 너무나 마음에 들었다.
전원을 켜고 기존의 iPhone 7 데이터를 iPhone 12 Pro로 전송하고 가동을 시작한 모습이다.
생각보다 폰의 무게감은 꽤 있었고, 마감이나 전체적인 모습들은 기대 이상으로 좋았다.


iPhone 12 Pro 개봉기는 이것으로 마치고자 한다.
당장 사용하고픈 마음에 사진도 기록도 생각만큼 하지는 못했지만, 앞으로 이 녀석을 사용하면서 느끼는 점들을 하나씩 정리해 보고자 한다.
4년 이나 함께한 iPhone 7은 막내 녀석의 세컨드 폰으로 사용되고 있다.















반응형

'IT제품' 카테고리의 다른 글

블루투스 스피커 만들기 (2/2)  (0) 2022.04.30
블루투스 스피커 만들기 (1/2)  (0) 2022.04.30
굿노트용 2022년 Calendar 일정관리  (0) 2021.11.27
애플워치 SE 개봉기  (0) 2020.11.30
반응형

오라클 패키지 내의 프로시저별로 사용하고 있는 테이블을 알고자 할 경우 유용한 쿼리 입니다.

 

SELECT X.OWNER,

       X.NAME,

       X.TYPE,

       X.PROCEDURE_NAME,

       X.TABLE_NAME,

       X.LINE

       || ' ~ '

       || X.LINE_NEXT AS LINE,

       X.TEXT         AS ORG_PROCEDURE_NAME

FROM   (SELECT A.*,

               Trim(Regexp_substr(A.TEXT, '(PROCEDURE\s+)(.+)(\()',

                    --> subexpressions ? ??? ???

                    1, --> ????

                    1, --> ????

                    'i', --> Matching Modifiers

                    2 --> 11g: subexpression to return as procedure_name

                    )) AS PROCEDURE_NAME,

               CASE

                 WHEN B.REFERENCED_LINK_NAME IS NOT NULL THEN

                 B.REFERENCED_NAME

                 || '@'

                 || B.REFERENCED_LINK_NAME

                 ELSE B.REFERENCED_NAME

               END     TABLE_NAME

        FROM   (SELECT /*+ NO_MERGE */ A.OWNER,

                                       A.NAME,

                                       A.TYPE,

                                       A.LINE,

                                       Lead(A.LINE, 1, 1000000)

                                         OVER (

                                           ORDER BY A.LINE) LINE_NEXT,

                                       A.TEXT

                FROM   DBA_SOURCE A

                WHERE  A.OWNER = :in_owner

                       AND A.NAME = :in_pkg_name

                       AND Regexp_like(A.TEXT, 'PROCEDURE', 'i')

                       AND ( A.TYPE = 'PACKAGE BODY'

                              OR A.TYPE = 'PROCEDURE' )) A,

               DBA_DEPENDENCIES B

        WHERE  B.OWNER = A.OWNER

               AND B.NAME = A.NAME

               AND B.TYPE = A.TYPE

               AND B.REFERENCED_TYPE = 'TABLE') X

WHERE  EXISTS (SELECT 'O'

               FROM   DBA_SOURCE S

               WHERE  S.OWNER = X.OWNER

                      AND S.NAME = X.NAME

                      AND S.TYPE = X.TYPE

                      AND S.LINE BETWEEN X.LINE AND X.LINE_NEXT

                      --                   and      regexp_like(s.text, x.table_name||'(\s|\n)+', 'i')

                      AND Regexp_like(S.TEXT, X.TABLE_NAME, 'i'))

ORDER  BY X.LINE,

          X.PROCEDURE_NAME,

          X.TABLE_NAME



출처: https://estenpark.tistory.com/330 [DATA 전문가로 가는 길]

반응형
반응형

안드로이드 개발을 하다보면 Intent를 이용해서 다른 앱의 기능을 호출해서 선택 또는 사용 후의 결과 값을 리턴 받아서 뭔가를 처리하는 작업들을 하게 된다.

이번에는 내부/외부 저장소의 Download 폴더 아래의 PDF 파일 목록을 파일관리자를 통해서 살펴보고, 선택한 PDF파일을 열어서 보여주는 기능을 개발하기 위한 방법을 설명하겠다.

 

안드로이드 빌드 버전에 따라서 파일을 공유할 수 있는 방법이 다르다.

내가 테스트 했던 기기는 LG X4+ 와 삼성 Galaxy Tab A 였다.

이 두 기기에서 다운로드 폴더를 열어서 PDF파일 목록을 보여주고, 선택한 PDF파일을 열어서 보여주고자 했는데 LG X4+ 기종에서는 문제가 없었으나, Galaxy Tab A에서는 PDF파일이 열리지 않는 문제가 발생했다.

이 문제를 해결하기 위해 구글링 하면 자료를 찾아보다 보니 안드로이드 버전에 따라 생기는 문제 임을 알게 되었다.

Android 8(LG X4+)과  Android 10(Galaxy Tab A)에서 파일 경로를 찾아오는 방법의 차이로 인해 생긴 문제 였다.

 

먼저 다운로드 폴드의 특정 폴더를 기준으로 파일 관리자를 열기 위한 방법이다.

면저 res폴더 아래에 xml 폴더를 생성하고 filepaths.xml파일을 생성한다.

Storage의 기본 위치를 지정.

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="storage/emulated" path="." />
</paths>

 

filepaths.xml 파일을 생성한 후에 AndroidManifest.xml 파일을 열어서 provider 를 추가하도록 한다.

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    android:requestLegacyExternalStorage="true"
    android:usesCleartextTraffic="true">
    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="패키지명"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/filepaths" />
        </provider>
    <activity android:name=".BarcodeActivity"></activity>
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

 

이렇게 설정을 하고 난 뒤에 MainActivity.Java 파일을 열어서 각각의 부분을 아래와 같이 수정한다.

파일관리자를 열어서 파일을 선택할 수 있도록 Intent를 startActivityForResult 로 실행하는 부분이다.

 

//파일이 위치한 폴더를 지정

File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS ).getPath() + "/하위폴드명칭/");

 

//안드로이드 버전 체크 (Android 8 버전이하와 이상으로 구분)
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    Uri uri = Uri.fromFile(file);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

    intent.setDataAndType(Uri.fromFile(file), "application/pdf");

    try {
        startActivityForResult(Intent.createChooser(intent, "File Select"), SELECT_FILE);
    } catch (ActivityNotFoundException ex) {
        Toast.makeText(this, "Please install a File Manager.", Toast.LENGTH_SHORT).show();
    }
} else {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("application/pdf");
    startActivityForResult(intent, SELECT_FILE);
}

 

startActivityForResult를 통해서 선택된 파일을 받아서 PDF파일을 열어주는 부분의 코드는 아래와 같다.

 

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == SELECT_FILE) {
        if (resultCode == FILE_SELECT_OK) {
            Uri uri = data.getData();
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) {
                String fileUri = data.getData().getPath();
                fileUri = fileUri.substring(fileUri.indexOf(":") + 1);
                File file = new File(fileUri);
                Intent intent = new Intent();
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.setAction(android.content.Intent.ACTION_VIEW);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                intent.setDataAndType(Uri.fromFile(file), "application/pdf");
                startActivity(intent);
        } else {
                String fileName = getFileName(uri);
                File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath() +

                                         "/하위폴드명칭/" + fileName);
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                Uri contentUri = FileProvider.getUriForFile(getBaseContext(), "패키지명", file);
                intent.setDataAndType(contentUri, "application/pdf");
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                startActivity(intent);
            }
        }
    }
    super.onActivityResult(requestCode, resultCode, data);

}

반응형
반응형

WANIGridDataTableDataSource에 할당하는 방법에 대해서 알아보자.

보통 우리는 데이터베이스에서 쿼리를 통해서 우리가 원하는 데이터들을 DataTable에 담아서 가져오게 되고, 이렇게 가져온 데이터를 특정한 양식 또는 원하는 화면에 사용자에게 제공하게 된다.

WANIGrid 또한 이렇게 가져온 데이터인 DataTable를 할당함으로써 WANIGrid에 원하는 컬럼의 정보들을 모두 제공할 수 있게 된다.

 

첨부된 WANIGridExample 프로젝트의 WANIGridExample.cs파일을 열어서 GridInitialize() 메소드를 살펴보자. WANIGrid를 사용하기 위해서는 항상 WANIGridHeader Column을 정의하고 WANIGrid에서 보여주고자 하는 DataTable의 정보를 할당하면 된다.

GridInitialize 메소드의 내부를 하나씩 살펴보기로 하자.

 

HeaderColumn 클래스의 List를 선언하고 waniGrid.TopHeaderList.GetHeaderList() 메소드를 호출해서 빈 headerColumns List를 생성한다.

List<HeaderColumn> headerColumns = waniGrid.TopHeaderList.GetHeaderList();

List<HeaderColumn> headerColumns를 새로 생성한다. Index 값이 0이고 ColumnId“LeftHeader”인 빈 컬럼 1개만 생성됨. 이 후에 각 컬럼들을 추가한다.

 

HeaderColumn 클래스의 속성과 메소드를 잠깐 살펴보자.

속성(Property)

get/set

상세

public int Index

get/set

컬럼 인덱스

public string ColumnId

get/set

컬럼 ID. DataTableColumn Name과 동일해야 함

public string Title

get/set

컬럼 헤더의 명칭.

public int Left

get/set

컬럼의 Left 즉 시작하는 X좌표 값

public int Width

get/set

컬럼의 폭

public HorizontalAlignment HeadAlign

get/set

컬럼 헤더 명칭의 정렬 방법

public HorizontalAlignment TextAlign

get/set

컬럼 데이터의 정렬 위치. DataTableRow별 컬럼 ID에 해당하는 데이터 값을 의미

public bool Visible

get/set

화면에서 해당 컬럼을 화면에 Display 여부. true면 보여지고 false인 경우 숨겨짐.

public bool Editable

get/set

컬럼의 데이터 편집 여부. true면 편집 가능 그렇지 않으면 편집 불가

public bool IsCalendar

get/set

컬럼이 날짜 정보를 가지고 있으면 true, 그렇지 않으면 false

public ViewRange

ViewRange

get/set

컬럼의 시작 X좌표와 끝 X좌표 값을 가지고 있는 ViewRange 타입.

 

WANIGrid를 초기화 하는 방법은 Header 영역을 초기화하고, Header영역의 컬럼들을 정의하는 것으로 일차적인 초기화를 하게된다.

Header영역을 Clear하고 HeaderColumn 목록을 초기화한다.

List<HeaderColumn> headerColumns = waniGrid.TopHeaderList.GetHeaderList();

DataTable의 각 컬럼명과 ColumnId를 동일하게 부여하면 DataTableColumn 값이 WANIGrid의 컬럼에 표시되게 된다.

headerColumns.Add(new HeaderColumn() { ColumnId = "Col01", Title = "Column 01", Width = 80, HeadAlign = HorizontalAlignment.Center, TextAlign = HorizontalAlignment.Left, Editable = true, Visible = true });

headerColumns ListHeaderColumn을 추가하면서 컬럼들을 하나씩 설정해 나가면 된다.

  • ColumnId DataTableColumn명과 동일하게 부여하면 DataTableColumn 값을 할당하게 된다.
  • Title WANIGrid의 컬럼 헤더에 표시되는 텍스트
  • Width 컬럼의 폭을 지정한다.
  • HeadAlign 헤더의 표시되는 텍스트 정렬 방법
  • TextAlign Column 값의 정렬 방법
  • Editable 편집 여부
  • Visible 화면에 표시 여부

컬럼의 속성을 설정해서 headerColumns 리스트를 waniGrid 컨크롤에 할당한다.

waniGrid.TopHeaderList.SetHeaderList(headerColumns);

WANIGrid 컨트롤에 할당한 컬럼 정보들을 InitializeHeader 메소드를 호출해서 초기화한다.

waniGrid.InitializeHeader();

WANIGrid 컨트롤에 고정 컬럼의 개수를 지정할 경우 FixedCol 속성에 고정 컬럼의 개수를 지정한다. 기본 값은 0이다.

waniGrid.FixedCol = 0;

 

아래의 첨부 파일을 실행하면 하기와 같은 화면을 볼 수 있다.

[그림 2-1] WANIGridExample 실행화면

고정컬럼 개수를 변화시켜 보라. 고정컬럼의 영역이 무엇을 의미하는지 확인할 수 있을 것이다.

고정컬럼 수정을 체크했을 때 고정컬럼 영역을 클릭해보라. 값을 입력할 수 있는 텍스트 입력 컨트롤이 활성화 될 것이다.

행간격을 높이거나 줄여보라. 행 높이의 기본 값은 20이다.

DataTable에서 Data 가져오기 버튼을 클릭해 보라. 내부적으로 DataTable을 생성해서 생성된 DataTableWANIGridDataSource에 할당하면 아래의 같이 각 필드의 값이 DataTable의 값으로 채워지게 된다.

자세한 내용은 아래의 첨부된 소스를 참조해 보기 바란다.

 

WANIGridExample_20200514.zip
0.21MB
WANIGrid.dll
0.05MB

 

 

반응형

'WinForm > WANIGrid 컨트롤 공개' 카테고리의 다른 글

WANIGrid Control 개선 - Mouse Wheel 처리 추가  (0) 2021.04.13
WANIGrid Control 개선  (0) 2021.04.10
WANIGrid Control 사용법 1  (1) 2020.04.30
반응형

WANIGrid 는 데이터를 Grid 형태로 제공하고 행 추가 및 수정, 삭제 등의 기본적인 기능들을 제공하는 WinFormControl이다.

 

Grid Control 만들기를 연재하면서 스스로 공부하면서 정리한 내용으로 Grid Control 만들기의 소스를 좀 더 다듬고 개선해서 WinForm 개발 시에 무료로 제한없이 사용할 수 있도록 WANIGrid Control 만들어 갈 생각이다.

WANIGrid Control 사용에 필요한 속성 정보와 API 들을 정리하고 보다 쉽게 사용할 수 있는 매뉴얼을 제공해서 Windows 개발자들이 보다 손 쉽게 사용할 수 있도록 할 것이다. 

 

제공하는 WANIGrid Control과 예제 소스를 통해서 직접 사용해 보면서 추가 개발 또는 개선이 필요한 사항이 있으면 언제든 댓글로 알려주세요.

 

WANIGrid Control을 사용하기 위한 기본적인 속성과 구성을 살펴보자.

[그림 1] WANIGrid Control 구성

WANIGrid Control Client Size를 기준으로 보여지는 첫 번째 컬럼과 마지막 컬럼의 번호를 기준으로 가로 영역을 표현하고, 행 또한 첫 번째 행의 번호와 마지막 행의 번호를 기준으로 세로 영역을 표현하게 된다.

가로/세로 스크롤바를 움직임에 따라 컬럼과 행의 시작/마지막 번호가 변경되며 이 값을 기준으로 표현되어야 할 데이터 영역을 표현하게 된다.

  • LeftHeader 영역은 첫 시작 컬럼이며 WANIGrid의 기본 컬럼이다. 폭의 기본 사이즈는 22이다.
  • XscHeight/YscWidth 영역은 가로/세로 스크롤바의 높이와 폭의 사이즈를 말한다.
  • RowHeight 는 각 행의 높이를 의미하며 기본 높이는 20의 값을 가지고 사용자가 변경할 수 있다.
  • TopHeader 는 헤더 영역의 각 컬럼 속성 정보들을 담고 있다.
  • TopHeaderHeight 는 헤더 영역의 높이를 말하며 기본 높이는 20의 값을 가지고 사용자가 변경할 수 있다.
  • FirstVisibleCol/LastVisibleCol 은 화면 상에서 보여지는 첫 번째 컬럼의 Index와 마지막 컬럼의 Index 값을 가지고 있다.
  • FirstVisibleRow/LastVisinleRow 는 화면 상에서 보여지는 첫 번째 행의 Index와 마지막 컬럼의 Index 값을 가지고 있다.

WANIGrid Control에서 제공되는 기본 속성(Property)들을 아래와 같이 정리해 보았다.

Scope

Type

명칭

내용

public

Cell

ActiveCell

선택한 셀의 행/열 정보를 저장

public

int

RowHeight

행 높이를 설정 또는 반환

public

int

TopHeaderHeight

WANIGrid의 Top Header 영역의 높이를 설정 또는 반환

public

TopHeader

TopHeaderList

Top Header에 정의한 컬럼 목록을 가져온다

public

bool

LeftHeaderVisible

맨 왼쪽의 컬럼을 보여줄 경우 true, 그렇지 않으면 false

public

int

FixedCol

고정할 컬럼 개수. 스크롤 시에 고정되는 컬럼의 개수를 설정 또는 반환.

첫번째 컬럼부터 시작하며 컬럼의 Visiable 속성이 true인 컬럼의 개수만큼 고정이됨

public

int

XscHeight

가로 스크롤의 높이

public

int

YscWidth

세로 스크롤의 폭

public

bool

FixedColEditable

고정컬럼 영역의 값 수정 여부.

false인 경우 Column의 값을 수정할 수 없음

public

int

AllRowsHeight

헤더 영역을 제외한 행(Row)의 총 높이(길이) 값을 반환

public

RowCollection

Rows

행(Row) 정보를 담고 있는 RowCollection을 반환

public

List<int>

SelectedRows

선택된 행(Row)의 Index정보 목록을 반환

public

List<int>

SelectedCols

선택된 열(Column)의 Index정보 목록을 반환

public

bool

ReadOnly

WANIGrid의 내용을 읽기 전용으로 설정 또는 반환.

ReadOnly 값이 true인 경우 WANIGrid 내의 값을 변경할 수 없다.

 

WANIGrid Control 사용 예제를 담은 파일은 아래를 참조.

WANIGridExample_20200430.zip
0.21MB

반응형

'WinForm > WANIGrid 컨트롤 공개' 카테고리의 다른 글

WANIGrid Control 개선 - Mouse Wheel 처리 추가  (0) 2021.04.13
WANIGrid Control 개선  (0) 2021.04.10
WANIGrid Control 사용법 2  (0) 2020.05.14
반응형

내가 만든 컨트롤 위에서 특정 위치에 마우스를 가져 갔을 때 풍선도움말로 사용자에게 메시지를 주고 싶을 때가 있다.

User Control 상의 특정 좌표에 마우스가 오면 풍선도움말을 제공하는 방법이다.

 

먼저 User Control에 대한 핸들 정보를 가져와야 한다.

IWin32Window window = Control.FromHandle(사용자컨트롤.Handle);

//툴팁 생성

ToolTip toolTip = new ToolTip();

toolTip.AutomaticDelay = 500;

toolTip.AutoPopDelay = 5000;
toolTip.InitialDelay = 500;
toolTip.ReshowDelay = 100;

MouseHover 이벤트에서 특정 조건에 맞을 경우 아래의 내용으로 Show를 하면 풍선 도움말이 제공된다.

if (조건이 참이면) {

    toolTip.Show("풍선도움말", window, X좌표, Y좌표);

} else { //그렇지 않을 경우 풍선도움말을 숨긴다.

    toolTip.Hide(window);

}

 

 

반응형

+ Recent posts