2008-11-08 5 views
3

이전에는 내부에 System.Collections.Generic.List<Item> (Item은 내가 만든 클래스 임)을 래핑 한 클래스가있었습니다. 래퍼 클래스는 목록의 항목에 대한 합계, 평균 및 기타 계산을 제공하는 여러 가지 컬렉션 수준 속성을 제공했습니다. 나는이 주위에 BindingSource을 작성했으며 List<>과 다른 클래스는 BindingSource이며, 래핑 된 목록의 항목은 첫 번째 BindingSource을 통해 얻을 수 있었고 두 번째 래퍼 클래스의 컬렉션 수준 속성도 얻을 수있었습니다. 이렇게 만든 결합 소스와Derived List 클래스의 목록 항목과 연결되지 않은 속성에 데이터 바인딩하는 방법 List <T>

public class OldClass() 
{ 
    private List<Item> _Items; 

    public OldClass() 
    { 
    _Items = new List<Item>(); 
    } 

    public List<Item> Items { get { return _Items; } } 

    // collection-level properties 
    public float AverageValue { get { return Average() } } 
    public float TotalValue { get { return Total() } } 
    // ... other properties like this 

} 

: 최근

_itemsBindingSource = new BindingSource(oldClass.Items); 
_summaryBindingSource = new BindingSource(oldClass); 

, I는이 클래스를 변화 시키려고 유지 대신 System.Collections.Generic.List<Item>로부터 유도 될

단순화 된 예처럼 보이는 싸서 List<> 회원. 내 희망은 여분의 래퍼 레이어를 없애고 두 개 대신 BindingSource 하나만 사용하는 것이 었습니다. 그러나 이제 데이터 바인딩을 수행 할 때 목록의 모든 항목에 적용되는 속성 (예 : AverageValue)을 얻을 수 없다는 것을 알게되었습니다. 목록 항목의 속성 만 사용할 수 있습니다.

List<>Item s로 감싸는 것을 사용하도록 강요 당했습니까? 아니면 컬렉션 자체에 적용되는 속성뿐만 아니라 Item의 두 속성 모두에서 새 클래스를 저장할 수있는 방법이 있습니까?

답변

5

시스템에서는 IList (또는 IListSource)을 구현하는 모든 항목을 항목이 아닌 컨테이너로 취급합니다. 따라서 IList을 구현하는 모든 속성에 바인딩 할 수 없습니다. 따라서 컨테이너의 속성에 바인딩하려는 경우 캡슐화 (예 : 이미 가지고있는 것)이 가장 좋습니다.

그러나 많은 바인딩이 소스에서 점 표기법을 지원한다는 점에 유의해야합니다. 즉, "Items.SomeProperty"에 바인딩하거나 보조 속성 (일반적으로 DataMember)을 설정하여 하위 목록을 지정해야합니다.DataMember="Items"을 가지고 당신이 TextBoxAverageValue에 바인딩 할 수도 있습니다 즉,과 (같은 DataSource 포함) DataGridView -

이 단일 BindingSource을 할 수 있고, 계층 구조의 다른 수준에 바인딩 된 다른 컨트롤을 가지고있다. 대신 당신의 목록 래퍼 클래스를 만드는

0

여기서 문제는 하나의 클래스를 완전히 다른 목적으로 바인딩 (바인딩 측면에서)으로 사용하려는 것입니다.

예 : "AverageValue"속성은 모든 항목에 적용되는 전역 속성이기 때문에 각 항목에 의미가 없습니다.

어느 쪽이든, 귀하의 _itemsBindingSource가 ComboBox 또는 무언가를위한 것이며 _summaryBindingSource가 PropertyGrid (또는 이와 비슷한 것)에 해당한다고 생각합니다.

당신은 입니다 가 현재 상황에서 작업 (나는 당신이 실제로 무엇을하는지 모르기 때문에 나는 확신 할 수 없습니다) 수도이 무엇을 할 수 있는지 :

1) 귀하의 확인 " OldClass "는 IEnumerable을 구현하고 있습니다. 목록에서 열거 형을 반환하면됩니다. 그러면 "oldClass.Items"대신 "oldClass"에 바인드 할 수 있습니다.

2) "공개 목록 항목"을 속성 대신 ... 필드로 만들거나 "Browsable (false)"속성을 추가하여 PropertyGrid에 바인딩되지 않도록하십시오 (이것은 추측입니다). 이러한 바인딩을 사용 중인지 확실하지 않음).

0

, 당신은 확장 클래스 물론

public static class MyExtensions 
{ 
    public static float GetAverage(this List<Item>) 
    { 
     // implementation 
    } 

    public static float GetTotal(this List<Item>) 
    { 
     // implementation 
    } 
} 

(당신이 C의 3 #을 사용하는 가정)을 생성 간주 있고, 당신의 재산이 될 메소드 호출 (maybe C# 4 will fix this)하지만, 당신은 래퍼를 완전히 제거 할 것이다.

관련 문제