wpf2017.09.06 12:13

예를 들면 3이라는 숫자가 바인딩 되어 있고

이걸 3개월로 바꾸고 싶으면 Converter를 쓰면 되지만 일일이 만들기가 엄청 귀찮다


 <TextBlock Text="{Binding Month, StringFormat={}{0}개월}"/>


돈도 

<TextBlock Text="{Binding Money,StringFormat='##,#'}" />


이렇게 하면 300,000 형식으로 나온다.



Posted by 동동(이재동)
c#2017.08.01 12:14

소켓통신으로 사진을 받는데 소켓호출을 동시에 여러번하면 중구난방으로 되어서


파일 하나를 다운받으면 그 다음 파일을 다운받는 형식으로 바꾸었다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    /// <summary>
    /// 포토 파일을 받을때 비동기로 처리 하기때문에 큐에 넣어서 다운이 다 받아지면 그떄 다음파일을 다운받도록 도와주는 클래스
    /// 받을파일을 한꺼번에 저장해놓고 차례대로 다운된다.
    /// </summary>
    public static class QueueManager
    {
        private static List<Action> queue = new List<Action>();
 
        public static void Add(PhotoData pd)
        {
            queue.Add(() => { Managers.DataManager<PhotoData>.GetFProcessPhoto(pd); });
        }
 
        public static void Excute()
        {
            if (queue.Count == 0)
                return;
 
            queue[0]();
            queue.RemoveAt(0);
        }
    }



Action을 이용해서 List에 소켓통신호출을 하고 리시브 받았을때 excute를 실행해서


큐에서 차례대로 파일이 전송되게 구현하였다.


Posted by 동동(이재동)
c#2017.07.27 12:38

간단한거지만 모를수도 있는분들을 위해 적어본다.

string.Format("{0}분", diffTime.Minutes.ToString("##"));


이렇게 하면 1분 2분으로 나오고

string.Format("{0}분", diffTime.Minutes.ToString("00"));


이렇게 00으로 하면 01분 02분으로 나온다.


자세한건 TimeSpan format을 확인하자~








Posted by 동동(이재동)
c#2016.10.18 17:07

C#을 처음 접하면 이런 내용을 접할 수 있다.


C#은 가비지 컬렉터가 메모리 해제를 자동으로 해줘서 메모리 해제를 안해줘도 된다.


Object C로 아이폰 개발할때 메모리 해제 때문에 엄청 귀찮았던 기억이 난다.


근데 막상 실행해서 확인해보면 메모리가 해당 객체의 사용이 끝나도 바로 해제가 되지 않는다.

한마디로 메모리 해제가 정확히 언제되는지 모른다는것이다.(물론 가비지 컬렉터를 수동으로 실행할 수는 있다)


그렇다면 이방법을 어떻게 해결할까? 


답은 Using이다.

Using이 그냥 어떤 클래스나 객체를 사용한다고 '선언' 하는 부분으로 사용할 수 도 있지만


using(메모리를 할당받는 객체의 선언)

{

실행코드

}


이런식으로 감싸주면 Using문을 빠져나오는 시점에 메모리 해제를 시켜준다.


참고로 메모리를 할당하는 모든 객체는 기본적으로 IDispossable이라는 클래스를 상속받는다.


이 IDispossable이라는 객체가 바로 메모리를 해제하는 역활을 한다.




Posted by 동동(이재동)
c#2016.10.18 16:27


결과적으로보면 String은 내용을 수정할수 없고 새로운 인스턴스를 새로 생성해야 수정이 된다.(한마디로 읽기전용)

하지만 StringBuilder는 새로운 인스턴스를 새로 생성하지 않고 지정된값을 추가 수정 삭제를 하기 때문에

메모리 효율성, 속도면에서 String보다 유용하다.


실제로 내용을 수정 추가 하는 방식이 많이한다면 String보다는 StringBuilder를 사용하는게 훨신 효율적이다.


참고 : http://nowonbun.tistory.com/131


Posted by 동동(이재동)
c#2016.07.06 13:41

Linq가 없는 시절  페이징 할려면 


private List<Data> MakePhotoList(int startCount)
{
var tempPhotoList = new List<Data>();
int maxCount = startCount + 9;
for (int i = startCount; startCount < maxCount; startCount++)
{
tempPhotoList.Add(_photoList[i]);
}
return tempPhotoList;
}


이런식으로 해야만 했다.

하지만 Linq가 있으면

_photoList.Skip(startCount).Take(9).ToList();

한줄로 끝~


Posted by 동동(이재동)
c#2016.03.16 11:43


var isExist = _statsList.Where(c => c.ID == data.id).FirstOrDefault();


예전에는 요렇게 Where를 이용해서  isExist에 Null인지 아닌지 여부로 판단하였지만 


 var isExist =_statsList.Exists(c => c.ID == data.id);


요렇게 하는게 하면 bool 형으로 받아올수 있고 좀더 가독성도 좋기 때문에 앞으로 Exist를 많이 활용해야겠다.


Posted by 동동(이재동)
c#2015.09.02 16:58

집에 쓸데 없이 중복된 영상 및 파일이 너무 많아서 중복 제거 프로그램을 만들어 보았다.


물론 중복 제거 프로그램은 많이 있지만 외장하드가 여러개가 있으면 그 여러개에 대한 중복 파일은 찾아내지 못한다...


불편해서 그냥 내가 만들었다.


중복 체크 부분은 MD5, CRC32, SHA1 등등 여러가지를 실험해본 결과


그냥 MD5로 하였다. 그리고 영상 파일 같은 대용량 파일을 다 일일히 읽으려면 시간과 메모리 부족 문제를 해결해야 했기 때문에 파일 바이너리의 첫 부분과 끝부분의 일부분을 읽어서 MD5 코드로 만들어서 합쳤다 


정말 좋은 아이디어 인거 같다.. 심지어 상용 프로그램 보다 더 중복체크를 잘하고 스피드도 엄청 빠르다.


파일의 전체 체크가 아닌 첫 끝부분의 일부분만 체크한 결과이다.


DB는 XML로 할려고 하였으나 방대한 양과 파일로 여러가지 갖고 놀기 쉽게 하기 위해서 CompactSqlCe를 사용하였다.


using (var md5 = MD5.Create())

            {

                using (Stream stream = File.OpenRead(filePath))

                {

                    hash = md5.ComputeHash(readFile(stream));

                    hash2 = md5.ComputeHash(readFile2(stream));

                }

            }


            StringBuilder sb = new StringBuilder();


            for (int i = 0; i < hash.Length; i++)

            {

                sb.Append(hash[i].ToString("X2"));

            }


            StringBuilder sb2 = new StringBuilder();


            for (int i = 0; i < hash.Length; i++)

            {

                sb2.Append(hash2[i].ToString("X2"));

            }


            var temp = sb.ToString() + sb2.ToString();




   public MemoryStream readFile(Stream fs)

        {

            BinaryReader reader = new BinaryReader(fs);


            //reader.ReadBytes(0x1000);


            byte[] buffer = reader.ReadBytes(10000);


            return new MemoryStream(buffer);

        }


        public MemoryStream readFile2(Stream fs)

        {

            BinaryReader reader = new BinaryReader(fs);


            if (reader.BaseStream.Length > 1000)

            {

                reader.BaseStream.Seek(reader.BaseStream.Length - 1000, SeekOrigin.Begin);

            }

            byte[] buffer = reader.ReadBytes(10000);


            return new MemoryStream(buffer);

        }


중복이 많이 되는 코드지만 나만 쓸꺼라 그냥 남겨본다 






Posted by 동동(이재동)
c#2015.06.09 14:10

public static Bitmap ScreenCapture(string originalFileName)
        {
            string filePath = null;
            int count = 1;
            var pngFileName = string.Format("{0}{1}{2}", DateTime.Now.ToString("yyyyMMdd_HHmmss_"), originalFileName, ".jpg");

            if (Directory == null)
            {
                Directory = ConfigManager.PatientFolders[0];
            }
            while (true)
            {
                filePath = Path.Combine(Directory, pngFileName);
                FileInfo f = new FileInfo(filePath);
                if (f.Exists == true)
                {
                    pngFileName = string.Format("{0}({1}){2}", originalFileName, count, ".jpg");
                    count++;
                }
                else
                {
                    break;
                }
            }

            //작업 표시줄을 제외한 영역 크기
            int w = Screen.PrimaryScreen.WorkingArea.Width;
            int h = Screen.PrimaryScreen.WorkingArea.Height;

            //size 객체 생성
            Size s = new Size(w, h);

            //Bitmap 객체 생성
            Bitmap b = new Bitmap(w, h);

            //Graphics 객체 생성
            Graphics g = Graphics.FromImage(b);

            //Graphics 객체의 CopyFromScreen()메서드로 bitmap 객체에 Screen을 캡처하여 저장
            g.CopyFromScreen(0, 0, 0, 0, s, CopyPixelOperation.SourceCopy);
            String path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            b.Save(Directory + "\\" + pngFileName, ImageFormat.Png);
            return b;
            //pictureBox1.Image = b;
        }

 

평소에는 이렇게 CopyFormScreen이라는 편리한 함수를 이용해서 캡쳐를 했었다..

 

하지만 이상하게 판서프로그램에서 간혹 캡쳐가 잘안될때가 있는데 이럴때는 그냥 예전방식을 이용하니 잘되었다.

 

 //간혹 안되는 pc는 올드 방식 캡쳐를 쓴다.
        public static Bitmap OldStyleScreenCapture()
        {
            var originalFileName = "ScreenShot";
            int x = 0;
            int y = 0;

            //작업 표시줄을 제외한 영역 크기
            int w = Screen.PrimaryScreen.WorkingArea.Width;
            int h = Screen.PrimaryScreen.WorkingArea.Height;

            string filePath = null;
            int count = 1;
            var pngFileName = string.Format("{0}{1}{2}", DateTime.Now.ToString("yyyyMMdd_HHmmss_"), originalFileName, ".jpg");

            if (Directory == null)
            {
                Directory = ConfigManager.PatientFolders[0];
            }
            while (true)
            {
                filePath = Path.Combine(Directory, pngFileName);
                FileInfo f = new FileInfo(filePath);
                if (f.Exists == true)
                {
                    pngFileName = string.Format("{0}({1}){2}", originalFileName, count, ".jpg");
                    count++;
                }
                else
                {
                    break;
                }
            }

            IntPtr hDC = GetDC(IntPtr.Zero);
            IntPtr hMemDC = CreateCompatibleDC(hDC);
            IntPtr hBitmap = CreateCompatibleBitmap(hDC, w, h);

            IntPtr hOld = (IntPtr)SelectObject(hMemDC, hBitmap);
            BitBlt(hMemDC, -x, -y, w + x, h + y, hDC, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt);
            SelectObject(hMemDC, hOld);

            DeleteDC(hMemDC);
            ReleaseDC(IntPtr.Zero, hDC);

            Bitmap memoryImage = System.Drawing.Image.FromHbitmap(hBitmap);
            DeleteObject(hBitmap);
            String path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            memoryImage.Save(Directory + "\\" + pngFileName, ImageFormat.Png);

            return memoryImage;
        }

Posted by 동동(이재동)
c#2015.03.09 16:45

.net framework4 에서의 dynamic은 굉장히 편하게 사용된다.

 

예를 들면

 

 private void xQuitButton_Click(object sender, RoutedEventArgs e)
        {

var ctl = sender is Button;

ctl.Quit();

   }

 

하지만 간단하게 dynmic을 이요하면

 

 private void xQuitButton_Click(dynmaic sender, RoutedEventArgs e)
        {

sender.Quit()

  }

 

 

이렇게 코드를 줄일수 있다...

 

머 다 아는거지만

 

물론 쓰임은 다르지만 귀찮게 interface만들고 이런작업을 간략하게 해보자

 

 

 

 

 

 

Posted by 동동(이재동)
c#2015.01.15 13:49

 

요즘은 linq가 잘되있어서 삭제 하기 쉽지만

 

그렇지 못한 경우 예를 들면 scatterviewitem 이나 ui의 item들은

 

var data=new List<string>(){"One","Two","Three"};
for(int i=data.Count - 1; i > -1; i--)
{
    if(data[i]=="One")
    {
        data.RemoveAt(i);
    }
}

 

이런식으로 for를 역으로 돌려서 삭제 하면 된다.

 

http://stackoverflow.com/questions/7340757/c-sharp-list-removing-items-while-looping-iterating

Posted by 동동(이재동)
c#2013.08.19 17:49

사내 세미나를 무사히 마쳤다~

 

서로 다른 NAT 환경에서 클라이언트끼리 서버를 거치지 않고 이미지 전송 및 글 전송까지 완벽하게 구현 및 시연 하였다.

 

일단 제대로 만들려면 공을 많이 들여야 할듯~

 

PPT

 

P2P를 연결을 위한 여러기술.pptx

 

C#으로 구현한 홀펀칭 서버와 클라이언트 샘플 예제 소스(이미지 전송 및 글 전송)

 

HolePunch.zip

 

 

이미지 업로드 추가한 버전(발표때 쓴버전)

 

HolePunch .zip

 

 

 

 

Posted by 동동(이재동)
c#2013.07.05 10:21

 

GW-basic때나 쓰던 goto문을 활용할수 있다.

 

예를 들면 랜덤함수를 돌린 List<int>를 서로 비교 해서 지난번에 돌린 거와 같지 않으면 다시 랜덤함수를 돌리는것이다.

 

 

//이전꺼와 같을시에 다시 썩는다.
          if (RandomPlayIndexList != null || RandomPlayIndexList.ToList().Count != shuffleList.Count)
          {
              var isDifferent = false;
              for (int i = 0; i < RandomPlayIndexList.ToList().Count; i++)
              {
                  if (RandomPlayIndexList.ToList()[i] != shuffleList[i])
                  {
                      isDifferent = true;
                  }
              }
              if (isDifferent == false)
                  goto again;
          }

 

goto again 이라고 있다 이부분은 이렇게 설정 가능하다

 

 

 
            bool isAgain = false;
 
        again:
            if (isAgain)
            {
                await Task.Delay(500);
            }

 

한번더 메소드를 실행하고 싶을때 유용할듯 싶다

Posted by 동동(이재동)
TAG c#, Goto, 랜덤
c#2013.07.04 15:10


보통 저렇게 넣을경우


Collection was modified; enumeration operation may not execute.


이런 에러가 난다.


해결방법은


-예전 가장 쉬운방법

http://www.dotnetperls.com/invalidoperationexception


-for문 사용하는 방법


-혹은 new list에 저장하는 방법


for 문을 사용하시는 것이 좋겠지만, foreach 문을 사용하시는 것을 선호하신다면, 
사용하시는 _dataList 의 크기가 크기 않다는 가정하에, 

foreach( Data data in new List<Data>(_dataList) ) 

    .... 
    _dataList.Remove(data); 
    .... 


http://www.devkorea.co.kr/bbs/board.php?bo_table=m03_qna&wr_id=19169&page=7&currentId=108


-tolist()를 붙이는 방법

http://stackoverflow.com/questions/604831/collection-was-modified-enumeration-operation-may-not-execute


등등이 있지만


가장 쉬운건 new list에 저장하는 방법이다


Posted by 동동(이재동)
c#2013.05.16 19:02

만약 {0:n}을 쓰면

1,234.00

 

이런식으로 나온다.

 

이걸 1,234로 나오게 하고 싶으면

 

String.Format("{0:#,###0}", value);

 

Posted by 동동(이재동)
c#2012.05.04 16:54
public static class DispatcherHelper
    {
        public static void DelayInvoke(this Dispatcher dispatcher, TimeSpan ts, Action action)
        {
            DispatcherTimer delayTimer = new DispatcherTimer();
            delayTimer.Interval = ts;
            delayTimer.Tick += (s, e) =>
            {
                delayTimer.Stop();
                action();
            };
            delayTimer.Start();
        }
    }

사용은

Dispatcher.DelayInvoke(TimeSpan.FromMilliseconds(1000),
                 new Action(() =>
                 {
                     FadeAnimationControl.Fade(InputTextBoxCotainer, 0.0, 1.0, 0.1); 
                 }));

 

참고 : http://stackoverflow.com/questions/8116266/animate-text-display-on-a-textblock-wp7

Posted by 동동(이재동)
c#2012.05.04 14:15

if (Regex.IsMatch(emailAddress, "^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\\-+)|([A-Za-z0-9]+\\.+)|([A-Za-z0-9]+\\++))*[A-Za-z0-9]+@((\\w+\\-+)|(\\w+\\.))*\\w{1,63}\\.[a-zA-Z]{2,6}$") == false)
            {
                errorMessage = "Email 형식이 올바르지 않습니다.";
                return false;
            }

Posted by 동동(이재동)
Windows Phone 72011.12.16 10:32

%를 사용하여 10으로 나눈 나마지을 빼버리면 간단~~

 

금액 = 금액 - (금액 % 10) 

 

ex)

324 - ( 324 % 10 ) = 320

Posted by 동동(이재동)
wcf2011.05.31 15:45

프로시저를 만들고 이제 WCF 서비스에서 프로시저를 실행을 하기 위해서 DB 연동을 해야 한다.

 

그냥 프로젝트에서 new item 후 Data 에 linq to sql classes를 선택 한다.

image

 

 

그뒤에 생성된 dbml에 Table과 프로시저를 드래그앤 드랍하면 끝~

image

 

호출은 이렇게 하면 된다.

 

public void InsertSubScriber()
        {
            using (DataClassesDataContext context = new DataClassesDataContext())
            {                
                context.sp_WP7Subscribers_Insert(1,"himan",DateTime.Now);
            }
        }

 

쉽다

Posted by 동동(이재동)
c#2011.02.01 15:28

휴즈플로우 CTO배 코딩 컨테스트에 올렸던 방법이다.

 

public partial class MainPage : UserControl
   {
       public MainPage()
       {
           InitializeComponent();
 
           List<string> names = new List<string>()
           {
               "한윤진",
               "이재동",
               "배은미",
               "윤병걸"
           };
      
           // 출력은 다음과 같길 기대합니다.
           // 한윤진, 이재동, 배은미, 윤병걸
           DateTime start = DateTime.Now;            
           OutputText.Text = GetConcatenatedString(names);
           //var temp = GetConcatenatedString(names); //100만개 테스트 했을때 ui에 채워넣기가 힘들어서 temp에 넣어서 테스트
           DateTime end = DateTime.Now;
 
           Debug.WriteLine("time :  "+ (end - start).ToString());
       }
 
       private string GetConcatenatedString(List<string> names)
       {            
           if (names == null)
               return string.Empty;
 
           Debug.Assert(names !=null,"name는 null이 들어오면 안됩니다.");
           Debug.Assert(names.Count > 0, "list 개수가 0개보다 커야 합니다.");
 
           if (names.Count > 10000)
          { 
               //string builder
               StringBuilder sb = new StringBuilder();
               for (int i = 0; i < names.Count; i++)
               {
                   sb.Append(names[i]);
                   if (i != names.Count - 1)
                   {
                       sb.Append(", ");
                   }
               }
               return sb.ToString();
           }
           else
           { 
               //Join                
               return String.Join(", ", names); 
           }            
      
           //Concat은 join이랑 속도가 비슷해서 Join으로 선택 하지만 Concat이 약간 더 빠름
 
           //Concat
           //String[] stringsForConcat = new String[names.Count];
           //for (int i = 0; i < names.Count; i++)
           //{
           //    stringsForConcat[i] = names[i];
           //    if (i != names.Count - 1)
           //    {
           //        stringsForConcat[i] += ", ";
           //    }
           //}            
           //return string.Concat(strings);
 
           //return sb.ToString();
           //return String.Join(",", stringsForConcat);
           //return string.Concat(strings);
       }
   }
 
난 3가지 방법으로 테스트 하였으나
 
return String.Join(", ", names); 

이방법이 젤 깔끔하고 좋은거 같다.
 
한줄 코딩…
 
심사기준은 이랬다
 

심사기준
심사기준은 다음과 같습니다.
 
1. 코드가 보기 좋았더라. (보기 좋은 코드, 기본으로 코딩 컨벤션 지켜주시고.)
2. 기술점수
3. 퍼포먼스 (100만개의 이름을 대상으로 TimeAttack)

'c#' 카테고리의 다른 글

[c#] DelayInvoker 구현  (0) 2012.05.04
[C#] Email Validation  (0) 2012.05.04
[c#] 문자열 병합 하기  (1) 2011.02.01
[c#] 자식폼에서 부모폼으로 이벤트 전달  (1) 2010.12.20
[c#] 단축키 구현  (0) 2010.07.01
[C#] 해당 값이 숫자인지 아닌지 체크  (1) 2010.06.21
Posted by 동동(이재동)
c#2010.12.20 20:12

자식폼에서 작업을 진행한후 그 결과값을 부모  폼에 적용하고 싶을때가 있다.

 

내가 하고 싶었던것은

 

자식창을 하나 열어서 coin정보를 add하고 add가 끝나면 닫고 그 부모폼의  listbox를 갱신하고 싶었다.

 

[자식폼]

// delegate 이벤트선언

public delegate void FormSendDataHandler(object obj);

public event FormSendDataHandler FormSendEvent;

 

// 창을 닫을 때 FormSendEvent 이벤트를 실행한다. 파라미터로 object 를 하나 넘긴다.

private void btnFormClose_Click(object sender, EventArgs e)

{

   int no = cboDisSystem.SelectedIndex;

   this.FormSendEvent(disSystemNos[no]);

   this.Dispose();

}

[부모폼]

// 자식폼을 실행할 때 자식폼에 설정되어있는 이벤트에 DieaseUpdateEventMethod

// 실행할 메소드명을 등록한다. 자식폼에서 이벤트를 실행하면 이 메소드가 실행될것이다.

private void btnReasonAdd_Click(object sender, EventArgs e)

{

    FrmAdd frm = new FrmAdd ();

    frm.FormSendEvent += new FrmAdd.FormSendDataHandler(DieaseUpdateEventMethod);

    frm.ShowDialog();

}

 

private void DieaseUpdateEventMethod(object sender)

{

    Console.WriteLine("이벤트 실행");

}

 

간단히 정리하자면 자식폼에서는 대리자 이벤트를 등록하고

부모폼에서는 자식폼 실행할 때 다음과 같이 함수를 등록해두면 된다.

frm.FormSendEvent += new FrmAdd.FormSendDataHandler(DieaseUpdateEventMethod);

 

이렇게 하면 된다.

 

자세한건 여기서 보자

참조 : http://mainia.tistory.com/402

'c#' 카테고리의 다른 글

[C#] Email Validation  (0) 2012.05.04
[c#] 문자열 병합 하기  (1) 2011.02.01
[c#] 자식폼에서 부모폼으로 이벤트 전달  (1) 2010.12.20
[c#] 단축키 구현  (0) 2010.07.01
[C#] 해당 값이 숫자인지 아닌지 체크  (1) 2010.06.21
[c#] Custom DateTime 과 Parser  (0) 2010.06.18
Posted by 동동(이재동)