솔루션의 프로젝트들의 전체 라인수를 알아내는 방법


분석 > 코드 메트릭 계산 > 솔루션

* '선택한 프로젝트'를 선택하면 프로젝트만 결과 도출

아래처럼 각 프로젝트별/ 네입스페이스별 라인수가 보여진다.

액셀버튼을 이용해 액셀파일로도 저장할 수 있다. (노란색 네모박스 표시)

액셀 저장 결과




특정파일을 Windows  탐색기를 열어 선택하게 하는 코드

1.

using System.IO;

string filePath = @"D:\test.txt"; // 선택할 파일 


if (!File.Exists(filePath))

{

    return;

}


string argument = "/select, \"" + filePath + "\"";


System.Diagnostics.Process.Start("Explorer.exe", argument);



2.

[DllImport("shell32.dll", ExactSpelling = true)]

public static extern void ILFree(IntPtr pidlList);


[DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]

public static extern IntPtr ILCreateFromPathW(string pszPath);


[DllImport("shell32.dll", ExactSpelling = true)]

public static extern int SHOpenFolderAndSelectItems(IntPtr pidlList, uint cild, IntPtr children, uint dwFlags);


string filePath = @"D:\test.txt"; // 선택할 파일 


var pidl = ILCreateFromPathW(filePath);

SHOpenFolderAndSelectItems(pidl, 0, IntPtr.Zero, 0);


ILFree(pidl);



두 테이블 간 조인을 할때 NOT IN 조건으로 JOIN 을 할 경우 처리하는 방법이다.

아래 예제 에서는 B 테이블의 value 컬럼의 내용을 NOT IN 조건으로 처리한다.

1. 

SELECT  A.*
FROM    A LEFT JOIN B ON A.value = B.value
WHERE   B.value IS NULL


2.

SELECT  A.*
FROM    A
WHERE   value NOT IN
(
SELECT  value
FROM    B
)

3.

SELECT  A.*
FROM    A
WHERE   NOT EXISTS
(
SELECT  value
FROM    B
WHERE   B.value = A.value
)


value 컬럼이 인덱스처리가 된 경우 성능차이는 없다고 한다.

그러나 value 컬럼이 NOT NULL임을 보장하지 않는 경우 하위 쿼리 결과 집합에 NULL 값이 있는지 여부에 따라 

다른 결과가 생성되므로 NOT IN 대신 LEFT JOIN / IS NULL 또는 NOT EXISTS를 사용해야한다.

참고

https://explainextended.com/2009/09/17/not-in-vs-not-exists-vs-left-join-is-null-oracle/

아래 코드를 이용하면 캡쳐를 방지할 수 있습니다.

using System;

using System.Drawing;

using System.Runtime.InteropServices;

using System.Windows.Forms;


namespace WindowsFormsApp

{

    public partial class MainForm : Form

    {

        private const uint WDA_NONE = 0;

        private const uint WDA_MONITOR = 1;


        [DllImport("user32.dll")]

        private static extern uint SetWindowDisplayAffinity(IntPtr windowHandle, uint affinity);


        public MainForm()

        {

            InitializeComponent();


            this.onButton.Click  += OnButton_Click;

            this.offButton.Click += OffButton_Click;

        }


        private void OnButton_Click(object sender, EventArgs e)

        {

            this.onButton.BackColor  = Color.White;

            this.offButton.BackColor = Color.Transparent;


            SetWindowDisplayAffinity(this.Handle, WDA_MONITOR);

        }


        private void OffButton_Click(object sender, EventArgs e)

        {

            this.onButton.BackColor  = Color.Transparent;

            this.offButton.BackColor = Color.White;


            SetWindowDisplayAffinity(this.Handle, WDA_NONE);

        }

    }

}



* 캡쳐도구를 이용해 캡쳐방지를 하지 않고 했을 때와  캡쳐방지를 켜고 했을 때 비교

(캡쳐방지를 켠 경우에는 녹화할 때도 검게변한다^^)


반디캠, 칼무리, 캡쳐도구, Print Screen 을 이용해 캡쳐 동작을 취할경우 검은 화면으로 보이게 된다.

메서드 호출시 메서드 안에서 어디에서 호출된 것인지 알고 싶을때가 있다

특히 로그 남길 때 유용하게 쓸수 있다.

아래 코드 처럼 메서드 인자로 [CallerMemberName], [CallerFilePath], [CallerLineNumber] 를 선언해 주면 알아서 내용이 들어가게된다.


using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Windows.Forms;

namespace CompilerServicesTest
{
    public partial class TestForm : Form
    {
        public TestForm()
        {
            InitializeComponent();

            CallMethod();
        }

        private void CallMethod()
        {
            WriteLog("CompilerServices Test!!");
        }

        private void WriteLog(string message,
           [CallerMemberName] string memberName = "",
           [CallerFilePath]   string sourceFilePath = "",
           [CallerLineNumber] int sourceLineNumber = 0)
        {
            Trace.WriteLine("message: " + message);
            Trace.WriteLine("member name: " + memberName);
            Trace.WriteLine("source file path: " + sourceFilePath);
            Trace.WriteLine("source line number: " + sourceLineNumber);
        }
    }
}



참고

https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/attributes/caller-information

일반적으로 GridView 에서 키보드로 포커스이동이 아래 처럼 포커스가 행의 끝으로 가면

다음 행으로 넘어가게 되어있다.

이를 다음행으로 넘어가지 않고 그 행에 두고 싶다면 아래 코드를 추가해 주면된다.

this.gridView.OptionsNavigation.AutoMoveRowFocus = false;

아래 처럼 포커스 이동시 다음행으로 넘어가지 않는다.


XtraGrid 의 GridView 의 KeyDown 이벤트는 Cell 내부 값을 입력하는 경우에 이벤트가 발생되지 않는다.

Cell 내부의 KeyDown 이벤트를 주고싶은때는 

GridControl 의 EditorKeyDown 이벤트를 사용하면 된다.


아래코드를 보면 알수 있지만 Cell 값 편집모드에서 GridView 의 KeyDown 이벤트는 처리 되지 않는다.

        this.gridView.KeyDown += GridView_KeyDown;


        private void GridView_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.V && e.Control)
            {
                string clipBoard = Clipboard.GetText();

                if (!string.IsNullOrEmpty(clipBoard))
                {
                    MessageBox.Show(clipBoard);
                }
            }
        }

     

하지만 아래처런 GridControl 의 EditorKeyDown 이벤트로 처리하면 Cell 값 편집모드에서 KeyDown 이벤트가 처리된다.

        this.gridControl.EditorKeyDown += GridControl_EditorKeyDown;


        private void GridControl_EditorKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.V && e.Control)
            {
                string clipBoard = Clipboard.GetText();

                if (!string.IsNullOrEmpty(clipBoard))
                {
                    MessageBox.Show(clipBoard);
                }
            }
        }


하단에 메뉴가 있고 배경이 여러이미지로 슬라이딩되면서 변경되는 화면을 구성하는 방법을 소개한다.


우선 Grid 를 배치하고 Grid 안으로 CarouselView 를 위치하고 좌측 상단에 로고 이미지를

하단에는 메뉴 아이콘을 배치했으며 이미지가 가로로 스크롤이 되도록 CarouselView 의  ItemsLayout 속성을 "HorizontalList" 으로 설정한다.

<?xml version="1.0" encoding="utf-8" ?>

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"

             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"

             xmlns:d="http://xamarin.com/schemas/2014/forms/design"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             mc:Ignorable="d"

             x:Class="SlideImage.MainPage">


    <StackLayout Margin="0" Padding="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="Black">

        <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Margin="0" Padding="0" ColumnSpacing="0" RowSpacing="0" BackgroundColor="White">

            <CarouselView  x:Name="mainView" ItemsLayout="HorizontalList" Margin="0" BackgroundColor="LightYellow" HorizontalScrollBarVisibility="Always">

                <CarouselView.ItemTemplate>

                    <DataTemplate>

                        <Image Source="{Binding ImageSrc}" Aspect="Fill"/>

                    </DataTemplate>

                </CarouselView.ItemTemplate> 

            </CarouselView>


            <Image Source="keisoft_textlogo.png" WidthRequest="100" HeightRequest="30" VerticalOptions="Start" HorizontalOptions="Start" Margin="10,0,0,0"/>


            <StackLayout VerticalOptions="End" Padding="0,0,0,20" HorizontalOptions="Center" Orientation="Horizontal" Spacing="20">

                <Image Source="main_store.png" WidthRequest="60" HeightRequest="60" >

                    <Image.GestureRecognizers>

                        <TapGestureRecognizer Tapped="StoreButton_Clicked"></TapGestureRecognizer>

                    </Image.GestureRecognizers>

                </Image>

                <Image Source="main_menu.png" WidthRequest="60" HeightRequest="60" >

                    <Image.GestureRecognizers>

                        <TapGestureRecognizer Tapped="MenuButton_Clicked"></TapGestureRecognizer>

                    </Image.GestureRecognizers>

                </Image>

                <Image Source="main_order.png" WidthRequest="60" HeightRequest="60" >

                    <Image.GestureRecognizers>

                        <TapGestureRecognizer Tapped="CartButton_Clicked"></TapGestureRecognizer>

                    </Image.GestureRecognizers>

                </Image>

                <Image Source="main_member.png" WidthRequest="60" HeightRequest="60" >

                    <Image.GestureRecognizers>

                        <TapGestureRecognizer Tapped="PersonButton_Clicked"></TapGestureRecognizer>

                    </Image.GestureRecognizers>

                </Image>

            </StackLayout>

        </Grid>

    </StackLayout>

</ContentPage>


여기에 일정 시간 간격으로 이미지가 자동으로 스크롤이 되도록 Timer 를 이용해 처리하면 아래 와 같은 화면이 완성된다.

Device.StartTimer(TimeSpan.FromSeconds(3), (Func<bool>)(() =>
{
    this.mainView.Position = (this.mainView.Position + 1) % 3;
    return true;
}));


자동으로 가로로 스크롤 되며 터치로도 슬라이드 동작을 하면 스크롤 된다.


* 이미지는 저작권이 있으므로 마음대로 쓰면 안됨.


소스

https://github.com/kei-soft/Slide-Image

Grid 에 Data 가 정형화 되어있지 않은 경우 특정 셀의 컬럼에 길이 제한을 두고 싶을 때 사용하는 방법이다.

아래는 LOT 컬럼이 5자가 넘는 경우 처리하는 방법으로 아래처럼 표시가 된다.

using System.Collections.Generic;
using System.Windows.Forms;

using DevExpress.XtraGrid.Views.Grid.ViewInfo;

namespace WindowsFormsApp
{
    public partial class MainForm : Form

    {
        public MainForm()
        {
            InitializeComponent();

            this.gridView.ValidatingEditor += GridView_ValidatingEditor;

            TestData testData1 = new TestData();
            testData1.LOT = "L001";
            testData1.WAFER = "01";

            TestData testData2 = new TestData();
            testData2.LOT = "L001";
            testData2.WAFER = "02";

            List<TestData> testDatas = new List<TestData>();
            testDatas.Add(testData1);
            testDatas.Add(testData2);
            this.gridControl.DataSource = testDatas;
        }

        void GridView_ValidatingEditor(object sender, DevExpress.XtraEditors.Controls.BaseContainerValidateEditorEventArgs e)
        {
            string value_string = e.Value.ToString();
            GridViewInfo viewInfo = gridView.GetViewInfo() as GridViewInfo;
            GridCellInfo cellInfo = viewInfo.GetGridCellInfo(gridView.FocusedRowHandle, gridView.FocusedColumn);

            if (cellInfo.Column.FieldName == "LOT")
            {
                if (value_string.Length > 5)
                {
                    e.ErrorText = "The value is too long";
                    e.Valid = false;
                }
            }
        }

        class TestData
        {
            public string LOT { get; set; }
            public string WAFER { get; set; }
        }
    }
}


TEST 테이블의 A 컬럼에 아래와 같이 데이터가 있을 때

A


A 컬럼의 데이터를 모두 ,(콤마) 로 연결하여 하나의 데이터("가,나,다")로 나타내고 싶은 경우

아래 처럼 listagg 를 이용해 쿼리하면 된다.


SELECT LISTAGG(A,' ,') RESULT FROM TEST


결과>

RESULT

가,나,다



+ Recent posts