2012-12-12 2 views
1

표준 목록 상자를 사용하여이를 개체 집합에 바인딩하고 바운드 항목 컬렉션을 업데이트하여 선택한 항목을 포함하고자합니다.Winforms 목록 상자의 SelectedItems를 바인딩합니다.

_pContext = new BindingSource(); 
_pContext.DataSource = _gpContext; 
_pContext.DataMember = "ParentEntities"; 
_AllChildrenListBox.DataSource = _container.ChildEntities; 
_AllChildrenListBox.DataBindings.Add("MySelectedItems", _pContext, "ChildEntities", false); 

_allChildrenListBox이 목록 상자입니다 :

그래서 내가 좋아하는 뭔가가있다. ListBox에서 상속받은 새 목록 상자 형식을 만들었으므로 항목을 설정/해제하기위한 논리를 캡슐화하는 대체 SelectedItems 속성을 만들 수있었습니다.

간단히 말하면 질문입니다. 위의 ChildEntities는 "ChildEntity"개체의 모음입니다. 내 목록 상자에 모든 가능한 ChildEntity 개체가 들어 있으며 ChildEntities의 요소를 선택하고 선택 항목을 변경하면 업데이트해야합니다.

답변

0

이 문제를 해결할 방법을 찾았습니다. 지금은 조금 추해 보이지 만 작동합니다. 나는 나중에 그것을 다듬을 수있다.

그래서 첫 번째 비트는 바인딩 자체입니다.

_AllChildrenListBox.DataBindings.Add("SelectedItems2", _pContext, "ChildEntities2", true); 

여기서 핵심은 서식 매개 변수를 true로 설정하는 것 같습니다.

다음으로 필자는 더러운 작업을 할 수있는 SelectedItems2가 필요한 것입니다. 이것은 엉망이지만 작동합니다. 여기에 전체 클래스이다 : 그것은 그 변화에 대한 기본 설정을 사용 않는 경우

public class MyListBox : ListBox 
{ 
    private IEnumerable<object> _original; 

    public IEnumerable<object> SelectedItems2 
    { 
     get 
     { 
      return UpdateSet(); 
     } 
     set 
     { 
      SelectItems(value); 
     } 
    } 

    private IEnumerable<object> UpdateSet() 
    { 
     var listSource = _original as IListSource; 
     IList list = null; 
     if (listSource != null) 
     { 
      list = listSource.GetList(); 
     } 
     var iList = _original as IList; 
     if (list == null && iList != null) 
     { 
      list = iList; 
     } 
     if (list == null) 
     { 
      return _original; 
     } 

     foreach (var item in SelectedItems) 
     { 
      if (!list.Contains(item)) 
      { 
       list.Add(item); 
      } 
     } 
     foreach (var item in _original.ToList()) 
     { 
      if (!SelectedItems.Contains(item)) 
      { 
       list.Remove(item); 
      } 
     } 

     return _original; 

    } 

    private void SelectItems(IEnumerable<object> items) 
    { 
     _original = items; 
     var hashset = new HashSet<object>(); 
     foreach (var item in items) 
     { 
      hashset.Add(item); 
     } 
     for(var i=0;i<Items.Count;i++) 
     { 
      SetSelected(i, hashset.Contains(Items[i])); 
     } 
    } 
} 

는 기본적으로 나는 모든 규칙을 위반하고는 IEnumerable을 가정하고있어, 더 맛있는 목록 기반 인터페이스를 숨 깁니다.

마지막으로 EF (Entity Framework)를 사용하고 있으며 컬렉션 속성의 setter를 호출 할 수 없으므로 현재 엔티티가 다음과 같이 보입니다. 전체 목록 변경 작업을 복제하는 방법에 유의하십시오. 불필요한,하지만 이건 그냥 첫 번째 작업이라고했습니다.

public partial class ParentEntity 
{ 
    public IEnumerable<object> ChildEntities2 
    { 
     get 
     { 
      return new List<object>(ChildEntities); 
     } 
     set 
     { 
      if (value == null) 
      { 
       return; 
      } 
      foreach (var item in ChildEntities.ToList().Where(item => !value.Contains(item))) 
      { 
       ChildEntities.Remove(item); 
      } 

      foreach (var item in value) 
      { 
       var cItem = item as ChildEntity; 
       if (cItem != null) 
       { 
        if (!ChildEntities.Contains(item as ChildEntity)) 
        { 
         ChildEntities.Add(item as ChildEntity); 
        } 
       } 
      }     
     } 
    } 
} 
+0

참고로, 이것은 실제 해킹이며 실제로 개념 증명입니다. 좀 더 깔끔한 접근법을 알고 있다면 나는 흥미로울 것이다. – Ian