# frequently used code

## GridControl, GridView

### FocusedRowChanged

```csharp
private void GridView_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
{
    if (sender is GridView view)
    {
        FocusedRowChanged(view);
    }
}

private void FocusedRowChanged(GridView view)
{
    if (view.Equals(gvwList))
    {
        if (view.RowCount > 0 && view.FocusedRowHandle >= 0)
        {
            if (string.IsNullOrEmpty(_findRowValue))
            {
                //// gvwList 에 행이 있을 때 처리할 코드
                //SetDataFromReferenceControl(grpMaster, grdList);
                //Func_P_SampleForm01_Q("detail");
            }
        }
        else
        {
            //// gvwList 에 행이 없을 때 처리할 코드
            //InitControls(grpMaster);
            //InitControls(grdDetail);
        }
    }
}
```

### Grid Keeping 처리, GridRowsCopy 호출 전 조건 검사

```csharp
private void AddKeepingDataRows(DataRow[] targetRows)
{
    if ((targetRows?.Length ?? 0) == 0)
        return;

    // 대상 DataRow에 같은 업체가 체크 되었는지 확인
    if (targetRows.Length > 1)
    {
        DataRow firstRow = targetRows.FirstOrDefault();
        string custcd = firstRow.GetValue("custcd")?.ToString() ?? string.Empty;
        string rcvcustcd = firstRow.GetValue("rcvcustcd")?.ToString() ?? string.Empty;

        if (targetRows.Any(x => !x.Equals(firstRow) && !(x.GetValue("custcd")?.ToString()?.Equals(custcd) ?? true)))
        {
            // 메시지 처리 (같은 업체끼리만 가능)
            return;
        }

        if (targetRows.Any(x => !x.Equals(firstRow) && !(x.GetValue("rcvcustcd")?.ToString()?.Equals(rcvcustcd) ?? true)))
        {
            // 메시지 처리 (같은 인수처끼리만 가능)
            return;
        }
    }

    // Keeping 검사
    if (gvwKeeping.RowCount > 0)
    {
        string custcd = gvwKeeping.GetValue(0, "custcd")?.ToString() ?? string.Empty;
        string rcvcustcd = gvwKeeping.GetValue(0, "rcvcustcd")?.ToString() ?? string.Empty;
        
        if (targetRows.Any(x => !(x.GetValue("custcd")?.ToString()?.Equals(custcd) ?? true)))
        {
            // 메시지 처리 (같은 업체끼리만 가능)
            return;
        }

        if (targetRows.Any(x => !(x.GetValue("rcvcustcd")?.ToString()?.Equals(rcvcustcd) ?? true)))
        {
            // 메시지 처리 (같은 인수처끼리만 가능)
            return;
        }
        
        // 중복 검사
        DataTable keepingDatas = grdKeeping.DataSource as DataTable;

        foreach (DataRow targetRow in targetRows)
        {
            string ordkey = targetRow.GetValue("ordkey")?.ToString() ?? string.Empty;
            
            if (keepingDatas.AsEnumerable().Any(x => x.GetValue("ordkey")?.ToString().Equals(ordkey) ?? false))
            {
                // 메시지 처리 (수주번호[] 는 이미 추가된 자료입니다)
                return;
            }
        }
    }

    // DataRow 복사 반복문
    foreach (DataRow targetRow in targetRows)
    {
        // 신규 행 추가
        DataRow newRow = GridAddNewRow(grdKeeping, gvwKeeping.RowCount);
        
        // 대상 DataRow의 컬럼을 반복
        foreach (DataColumn targetColumn in targetRow.Table.Columns)
        {
            // SetValue 확장 메서드는 존재하지 않는 ColumnName 일 경우 처리하지 않도록 예외 처리 되어 있음
            newRow.SetValue(targetColumn.ColumnName, targetRow.GetValue(targetColumn.ColumnName));
        }
        
        // 별도 DataColumn에 대한 처리
        newRow.SetValue("resultqty", targetRow.GetValue("janqty"));
    }
}
```

## TreeList

### FocusedNodeChanged

```csharp
private void TreeList_FocusedNodeChanged(object sender, FocusedNodeChangedEventArgs e)
{
    if (sender is TreeList tree)
    {
        FocusedNodeChanged(tree);
    }
}

private void FocusedNodeChanged(TreeList tree)
{
    if (tree?.Equals(treeList) ?? false)
    {
        var focusedNode = tree.FocusedNode;
        if (focusedNode != null && !tree.IsAutoFilterNode(focusedNode))
        {
            if (string.IsNullOrEmpty(_findRowValue))
            {
                //// focusedNode가 있을 때 처리할 코드
                //SetDataFromReferenceControl(grpMaster, grdList);
                //Func_P_SampleForm01_Q("detail");
            }
        }
        else
        {
            //// focusedNode가 없을 때 처리할 코드
            //InitControls(grpMaster);
            //InitControls(grdDetail);
        }
    }
}
```

## Find Row Pattern

### GridControl

{% tabs %}
{% tab title="Base" %}

```csharp
// 전역 필드 정의
private string _findRowValue = null;

// 조회 버튼
public override void ClickRetrieveButton()
{
    int beforeRowHandle = gvwList.FocusedRowHandle;
    int findIndex = 0;

    if (Func_P_SampleForm01_Q("list"))
    {
        if (!string.IsNullOrEmpty(_findRowValue))
        {
            findIndex = gvwList.LocateByValue("find_key", _findRowValue);
            
            if (findIndex == 0)
                beforeRowHandle = 0;
                
            _findRowValue = null; // findIndex를 찾고 초기화
            
            gvwList.FocusedRowHandle = findIndex;
        }
    }

    if (gvwList.FocusedRowHandle < 0
        || (beforeRowHandle <= 0 && gvwList.FocusedRowHandle == 0)
        || findIndex < 0)
    {
        FocusedRowChanged(gvwList);
    }
}
```

{% endtab %}

{% tab title="TabControl" %}

```csharp
// 전역 필드 정의
private string _findRowValue = null;

// 조회 버튼
public override void ClickRetrieveButton()
{
    int findIndex = 0;
    GridView view = null;
    string workType = string.Empty;

    if (tabMain.SelectedTabPage.Equals(tpgReceptions))
    {
        view = gvwReception;
        workType = "received";
    }
    else if (tabMain.SelectedTabPage.Equals(tpgProject))
    {
        view = gvwProjectDetail;
        workType = "project";
    }
    else if (tabMain.SelectedTabPage.Equals(tpgMeeting))
    {
        view = gvwMeetingList;
        workType = "meeting";
    }
    else if (tabMain.SelectedTabPage.Equals(tpgUnreferenced))
    {
        view = gvwTaskOrder;
        workType = "task_order";
    }

    int beforeRowHandle = view.FocusedRowHandle;

    if (Retrieve(workType))
    {
        if (!string.IsNullOrEmpty(_FindRowValue))
        {
            findIndex = view.LocateByValue("find_key", _FindRowValue);
            
            if (findIndex == 0)
                beforeRowHandle = 0;
                
            _FindRowValue = null; // findIndex를 찾고 초기화

            view.FocusedRowHandle = findIndex;
        }
    }

    if (view.FocusedRowHandle < 0
       || (beforeRowHandle <= 0 && view.FocusedRowHandle == 0)
       || findIndex < 0)
    {
        FocusedRowChanged(view, beforeRowHandle, view.FocusedRowHandle);
    }
}
```

{% endtab %}
{% endtabs %}

### TreeList

```csharp
// 전역 필드 정의
private string _findRowValue = null;

// 조회 버튼
public override void ClickRetrieveButton()
{
    int beforeNodeIndex = treeList.FocusedNode?.Id ?? -1;
    TreeListNode findNode = null;
    
    if (Func_P_SampleForm01_Q("list"))
    {
        if (!string.IsNullOrEmpty(_findRowValue))
        {
            findNode = treeList.FindNode(x => x["find_key"].Equals(_findRowValue));
            
            if (treeList.FocusedNode == findNode)
                beforeNodeIndex = 0;
                
            _findRowValue = null; // findNode를 찾고 초기화
            
            if (findNode != null)
            {
                findNode.ExpandToFirstNode(); // 첫번째 노드까지 확장
                treeList.FocusedNode = findNode; // Focus
            }
        }
        else
        {
            if (treeList.Nodes.Count > 0)
                treeList.Nodes.FirstNode.Expand();
        }
    }

    if (treeList.FocusedNode == null || treeList.IsAutoFilterNode(treeList.FocusedNode)
        || (beforeNodeIndex <= 0 && treeList.FocusedNode.Id == 0)
        || findNode == null)
    {
        FocusedNodeChanged(treeList);
    }
}
```

## Resize

* 사이즈를 동적으로 제어할 컨트롤의 부모 컨트롤에 이벤트 핸들러를 추가하고 다음과 같이 구현
* 예시 코드 설명
  * grpList의 너비를 제어하고 싶으면 grpList의 부모 컨트롤인 폼(this)
  * grpAnswer의 높이를 제어하고 싶으면 grpList의 부모 컨트롤인 panDetail

```csharp
public Form1()
{
    InitializeComponent();
    
    this.Resize += OnResize;
    panDetail.Resize += OnResize;
}

private void OnResize(object sender, EventArgs e)
{
    var control = sender as Control;
    int width = control.Width; // 이벤트 핸들러를 호출한 컨트롤의 너비
    int height = control.Height; // 이벤트 핸들러를 호출한 컨트롤의 높이

    if (sender.Equals(this))
    {
        grpList.Width = width / 3;
    }
    else if (sender.Equals(panDetail))
    {
        int tempHeight = height - panMaster.Height;

        grpAnswer.Height = tempHeight / 3;
    }
}
```

## DragDrop

### 윈도우 탐색기에서 파일 또는 폴더 드랍

* 생성자에 다음과 같이 처리

```csharp
public SY_TEST01() 
{
    InitializeComponent();
    
    // Control.AllowDrop 속성을 true로 설정
    grdList.AllowDrop = true;

    // Control.DragOver 이벤트 핸들러 생성 및 추가
    grdList.DragOver += (s, e) => e.Effect = DragDropEffects.Copy;

    // Control.DragDrop 이벤트 핸들러 생성 및 추가
    grdList.DragDrop += OnDragDrop;
}
```

* OnDragDrop 이벤트 핸들러

```csharp
private void OnDragDrop(object sender, DragEventArgs e)
{
    if (sender.Equals(grdList))
    {
        string[] files = e.Data.GetData(DataFormats.FileDrop) as string[];

        foreach (string filename in files)
        {
            // ...
        }
    }
}
```

###

### GridControl에서 선택된 행을 다른 GridControl로 드랍

* 전역 필드 정의

```csharp
private GridHitInfo _gridHitInfo = null;
```

* 생성자에 다음과 같이 처리

```csharp
public SY_TEST01() 
{
    InitializeComponent();
    
    // 드랍 대상 GridControl
    grdList.AllowDrop = true;
    grdList.DragOver += (s, e) => e.Effect = DragDropEffects.Copy;
    grdList.DragDrop += OnDragDrop;
    
    // 드래그 대상 GridView
    gvwRefData.MouseDown += OnMouseDown;
    gvwRefData.MouseMove += OnMouseMove;
}
```

* OnMouseDown 이벤트 핸들러

```csharp
private void OnMouseDown(object sender, MouseEventArgs e)
{
    if (sender is GridView view)
    {
        _gridHitInfo = null;

        GridHitInfo hitInfo = view.CalcHitInfo(new Point(e.X, e.Y));

        if (e.Button == MouseButtons.Left && Control.ModifierKeys == Keys.None)
            _gridHitInfo = hitInfo;
    }
}
```

* OnMouseMove 이벤트 핸들러

```csharp
private void OnMouseMove(object sender, MouseEventArgs e)
{
    if (sender is GridView view)
    {
        if (e.Button == MouseButtons.Left && _gridHitInfo != null)
        {
            Size dragSize = SystemInformation.DragSize;
            Rectangle dragRect = new Rectangle(new Point(
                _gridHitInfo.HitPoint.X - dragSize.Width / 2,
                _gridHitInfo.HitPoint.Y - dragSize.Height / 2), dragSize);

            if (!dragRect.Contains(new Point(e.X, e.Y)))
            {
                DataRow row = view.GetDataRow(view.FocusedRowHandle);
                if (row == null) return;

                view.GridControl.DoDragDrop(row, DragDropEffects.All);
                
                _gridHitInfo = null;
                DevExpress.Utils.DXMouseEventArgs.GetMouseArgs(e).Handled = true;
            }
        }
    }
}
```

* OnDragDrop 이벤트 핸들러

```csharp
private void OnDragDrop(object sender, DragEventArgs e)
{
    if (sender.Equals(grdList) && (_gridHitInfo?.View?.Equals(gvwRefData) ?? false))
    {
        DataRow dataRow = e.Data.GetData(typeof(DataRow)) as DataRow;
        
        //
        // ...
        //
    }
}
```

### TreeList에서 선택한 노드를 GridControl로 드랍

* 전역 필드 정의

```csharp
private TreeListHitInfo _treeHitInfo = null;
```

* 생성자에 다음과 같이 처리

```csharp
public SY_TEST01()
{
    // 드랍 대상 GridControl
    grdList.AllowDrop = true;
    grdList.DragOver += (s, e) => e.Effect = DragDropEffects.Copy;
    grdList.DragDrop += OnDragDrop;
    
    // 드래그 대상 TreeList
    treeRefData.MouseDown += OnMouseDown;
    treeRefData.MouseMove += OnMouseMove;
}
```

* OnMouseDown 이벤트 핸들러

```csharp
private void OnMouseDown(object sender, MouseEventArgs e)
{
    if (sender is TreeList tree)
    {
        _treeHitInfo = null;
    
        TreeListHitInfo hitInfo = tree.CalcHitInfo(new Point(e.X, e.Y));
    
        if (e.Button == MouseButtons.Left && Control.ModifierKeys == Keys.None)
            _treeHitInfo = hitInfo;
    }
}
```

* OnMouseMove 이벤트 핸들러

```csharp
private void OnMouseMove(object sender, MouseEventArgs e)
{
    if (sender is TreeList tree)
    {
        if (e.Button == MouseButtons.Left && _treeHitInfo != null)
        {
            Size dragSize = SystemInformation.DragSize;
            Rectangle dragRect = new Rectangle(new Point(
                _treeHitInfo.MousePoint.X - dragSize.Width / 2,
                _treeHitInfo.MousePoint.Y - dragSize.Height / 2), dragSize);

            if (!dragRect.Contains(new Point(e.X, e.Y)) && tree.FocusedNode != null)
            {
                tree.DoDragDrop(tree.FocusedNode, DragDropEffects.All);
                
                _treeHitInfo = null;
                DevExpress.Utils.DXMouseEventArgs.GetMouseArgs(e).Handled = true;
            }
        }
    }
}
```

* OnDragDrop 이벤트 핸들러

```csharp
private void OnDragDrop(object sender, DragEventArgs e)
{
    if (sender.Equals(grdList) && (_treeHitInfo?.Node.TreeList.Equals(treeRefData) ?? false))
    {
        TreeListNode node = e.Data.GetData(typeof(TreeListNode)) as TreeListNode;
        
        //
        // ...
        //
    }
}
```

## GroupControl

### Custom Button Click

```csharp
// 이벤트 핸들러 추가
grpList.CustomButtonClick += GroupControl_CustomButtonClick;
```

```csharp
private void GroupControl_CustomButtonClick(object sender, DevExpress.XtraBars.Docking2010.BaseButtonEventArgs e)
{
    (sender as Control).Focus();
    string tagValue = e.Button?.Properties?.Tag?.ToString() ?? string.Empty;
    
    if (sender.Equals(grpList))
    {
        // 행추가
        if (tagValue.Equals("add"))
        {
            // ...
        }
        // 행 삭제
        else if (tagValue.Equals("remove"))
        {
            // ...
        }
    }
    else if (sender.Equals(grpDetail))
    {
        // ...
    }
}
```

## GridView

### DoubleClick

```csharp
private void GridView_DoubleClick(object sender, EventArgs e)
{
    var view = sender as GridView;
    
    var dxMouseEventArgs = e as DevExpress.Utils.DXMouseEventArgs;
    GridHitInfo hitInfo = view.CalcHitInfo(dxMouseEventArgs.Location);
    
    if (hitInfo == null || hitInfo.InGroupRow || hitInfo.RowHandle < 0) 
        return;
        
    if (sender.Equals(gvwReceptionist))
    {
        // ...
    }
}
```

## XtraReport

### 90도 회전된 출력물 (샘플 코드)

```csharp
// 실제 출력할 원본 XtraReport 출력물 개체 생성
XtraReport1 originReport = new XtraReport1();

// 원본 XtraReport 개체를 Image로 변환하여 90도 회전
Image image = null;
using (MemoryStream ms = new MemoryStream())
{
    originReport.ExportToImage(ms);
    ms.Position = 0;
    image = Util.ConvertByteArrayToImage(ms.ToArray());
}
image.RotateFlip(RotateFlipType.Rotate90FlipNone);

// 위에서 만든 이미지를 사용하여 빈 XtraReport에 붙여넣음
XtraReport newReport = new XtraReport();
newReport.PaperKind = System.Drawing.Printing.PaperKind.Custom;
newReport.PageHeight = image.Size.Height;
newReport.PageWidth = image.Size.Width;
newReport.Landscape = image.Size.Width > image.Size.Height ? true : false;
newReport.Margins = new System.Drawing.Printing.Margins(0, 0, 0, 0);

var detail = new DevExpress.XtraReports.UI.DetailBand();
detail.HeightF = image.Size.Width > image.Size.Height ? image.Size.Height : image.Size.Width;
newReport.Bands.Add(detail);

var pictureBox = new XRPictureBox();
pictureBox.SizeF = image.Size;
pictureBox.Image = image;
detail.Controls.Add(pictureBox);

newReport.ShowPreviewDialog();
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://youngtae.gitbook.io/gst_platform/development-guide/frequently-used-code.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
