Saturday, February 8, 2014

ListView 아이템을 Drag and Drop으로 순서 바꾸기 Reorder ListViewItem

놀랍게도 ListView 아이템은 드래그앤드랍이 기본으로는 안 되는데, 더 놀라운 것은 이것이 버그라는 것이다. (오작동뿐 아니라 코드를 빠뜨려서 작동 안 하는 것도 버그이긴 하지...) 1)
http://support.microsoft.com/kb/822483/en-us


위 링크에서 제공하는 코드를 적당히 붙이는 것만으로도 drag & drop으로 순서를 변경하는 작업이 잘 된다.

단, ListViewItem.Name은 보존되지 않는다. 이러면 ListView.Items.RemoveByKey(string=Name)를 할 수 없게 된다.

이는 아마 ListView.Items 내에서의 순서 이동은, 실제로는 ListViewItem 객체의 복사(Clone()이 호출된다) 후 원본 ListViewItem 객체 삭제이므로, container 내에 같은 Name의 객체를 두 개 이상 가질 수 없기 때문일 것이다.
그래서 다음과 같이 Name을 재지정해야 한다.
        void listView1_DragDrop(object sender, DragEventArgs e)

        {
                //(전략)
                ListViewItem insertItem = (ListViewItem)dragItem.Clone();
                listView1.Items.Insert(itemIndex, insertItem);
                listView1.Items.Remove(dragItem);
             
                //dragItem을 Remove한 뒤 다시 설정해 줌:
                insertItem.Name = dragItem.Name; 

            }

물론 처음부터 Name을 쓰지 않고 있었다면 해 주지 않아도 된다.

참고로, 위 코드를 ListView에 적용하기 위해 핸들러를 만들어야 하는 이벤트는 ItemDrag, DragEnter, DragDrop의 3개이다.
IDE 디자이너의 '속성' 창에서 찾을 수 있긴 한데,
DragDrop, DragEnter는 "끌어서 놓기" 분류에,
ItemDrag는 "작업" 분류에 들어가 있어 찾기가 매우 어렵다.

그냥 코드로 치는 게 (적절히 tab하면 핸들러도 만들어 주니까) 편하다.


-----------------------
1) 의도된 사항(design)이라고 답변한 것이다.

No comments:

Post a Comment

창 핸들을 만드는 동안 오류가 발생했습니다

System.ComponentModel.Win32Exception was unhandled   MyForm w = new MyForm IntPtr handle = wnd.Handle;   // Exception occurs here class MyFo...