728x90

C#에 있는 WinForm을 이용하여 ListBox 상에 데이터를 추가할 때 여러가지 방법이 있지만
나름대로 상당히 좋은 방법이 있어 여기에 기록합니다.

ListBox 상에 데이터를 넣는 방법은 보통 ListBox 객체 내에 있는 items를 이용하여
추가/삭제를 시도하게 됩니다. 하지만, 만일 ListBox 내에 표시되는 내용과 실제 사용하게
될 데이터가 틀린 경우에는 조금 다른 문제가 발생합니다.

여기서는 두가지 방법을 제시하려 합니다.
첫번째 방법은 가장 일반적인 방법으로 ListBox.items 라는 콜렉션 내에 추가하는 방법입니다.
가장 직관적이고 빠르게 처리할 수 있는 방법이죠.
두번째 방법은 DataSource 속성을 이용해 별도 데이터를 담은 콜렉션을 만들어 이 ListBox와 연결해주는 방법입니다.


1. ListBox.items 를 이용하는 방법

2. DataSource를 이용한 방법


3. ListBox 데이터 바인딩 팁.
이 글을 쓰게된 가장 중요한 사항인데, 사실 DataSource를 이용해 데이터 객체와 바인딩 하고 난뒤 이후의 처리가 굉장히 황당한 경우가 있습니다. 특히 원본 데이터 부분을 업데이트 했는데도 불구하고, ListBox내의 내용이 전혀 변화가 없는 경우입니다.
처음에 저는 다음과 같은 함수를 만들어 위의 문제를 해결해 보려고 했었습니다.

[CODE] private void UpdateList(ListBox listbox, List<DataType1> list)        {            try            {                BindingManagerBase bm;                bm = listbox.BindingContext[list];                bm.CancelCurrentEdit();                bm.ResumeBinding();            }            catch (Exception ex)            {                MessageBox.Show(ex.Message);            }            listbox.Refresh();        } [/CODE]
보통 컨트롤 내에 데이터 바인딩 기법을 사용하게 되면 데이터 바인딩에 관련된 기능들을 이용할 수 있는데, 여기서 데이터 바인딩 매니저를 이용하여 업데이트 하게 끔 만든 것입니다.
그러나 최악의 문제가 원본 데이터가 완전히 비어 있는 경우 입니다.
이 경우 원본 데이터가 비어 있으므로 ListBox의 컨트롤 데이터가 전혀 변화가 없게 됩니다.
그래서 결국 위의 내용을 다음과 같이 변경 했습니다

[CODE] private void RebindingListBox(ListBox listbox, List<DataType1> list, string DisplayName, string ValueName)        {            listbox.DataSource = null;            listbox.DataSource = list;            listbox.DisplayMember = DisplayName;            listbox.ValueMember = ValueName;        } [/CODE]

코드를 보시면 알겠지만, 바로 바인딩 작업을 완전히 리셋한 뒤 다시 바인딩을 시도했습니다.
이 경우 바인딩 정보가 완전히 리셋되기 때문에, 원본 데이터 내용이 비어 있어도,
정상적으로 처리가 됩니다.

물론 위의 방법은 제가 발견한 팁일 분, 프로그래밍의 정답은 아닙니다.
개인적으로도 위의 방법은 비용이 조금 비쌀듯 해보입니다. 바인딩 정보를 완전히
날리고, 다시 재 바인딩 하기 때문에, 무언가 비용이 많이 들어갈 것 같습니다.
하지만, 현재 제가 발견한 방법 중에 확실하게 처리되는 것 같아 제시한 것입니다.

더 좋은 방법이나 다른 의견 있으시면 댓글을 통해 말씀해주시면 고맙겠습니다.
728x90
  1. waterbell 2012.05.18 16:59

    안녕하세요. 님의 글을 보고 도움이 많이 되었습니다.
    다른 곳(http://arstechnica.com/civis/viewtopic.php?f=20&t=554717)에서 본 내용을 약간 접목해서 다음과 같이 수정 해봤습니다...

    private void UpdateList(ListBox listbox, List<ParsingItems> list)
    {
    try
    {
    //BindingManagerBase bm;
    //bm = listbox.BindingContext[list];
    //bm.CancelCurrentEdit();
    //bm.ResumeBinding();

    CurrencyManager cm = (CurrencyManager)BindingContext[list];
    if (list.Count() == 0) // 다만, 요 부분이 맘에 걸리네요...
    cm.List.Clear(); // 어째 깔끔하지 못한 듯...
    cm.Refresh();
    }
    catch (Exception ex)
    {
    MessageBox.Show(ex.Message);
    }

    listbox.Refresh();
    listbox.ClearSelected();
    }

    모르겠는 점은... 'CurrencyManager cm = (CurrencyManager)BindingContext[list];' 에서
    cm의 DataSource의 count는 '0'가 되었는데, List는 '0' 되길 거부하는 듯... ㅠㅠ
    그래서 강제로 cm.List.Clear();를 한 것입니다.

    이만 줄이겠습니다..

+ Recent posts