2012-03-16 4 views
0

C#의 WPF DataGrid의 itemssource 멤버에 사용자 지정 클래스를 바인딩하려고합니다. IList를 구현했지만, 어떤 이유로 든 멤버를 표시 할 수있는 목록을 얻을 수 없습니다. 여기 세 가지 클래스를 가지고있는 이유는 사실 해결하기 위해 WPF의 DataGrid ItemsSource에 사용자 지정 데이터 구조 바인딩

public class AssetHolder<T> : Dictionary<string,T>, IList<T>, INotifyCollectionChanged, INotifyPropertyChanged where T : Asset 
    { 
     ... // lots of code here 
     new public IEnumerator<T> GetEnumerator() 
     { 
      var enumerator = base.GetEnumerator(); 
      while (enumerator.MoveNext()) 
      { 
       var pair = enumerator.Current; 
       yield return pair.Value; 
      } 
     } 
    } 
    public class NonGenericAssetHolder : AssetHolder<Asset> {} 
    public class SwitchHolder : NonGenericAssetHolder {} 

입니다

:

내가 여기

dataGridObject.ItemsSource = switchHolderObject 

를 호출하여 C 번호의 ItemsSource 속성을 설정하고있어 내 값에 대한 정의입니다 C#의 사전은 공변 적이 지 않습니다.

구현 된 모든 IList 메서드가 제대로 작동하고 목록이 확장되고 적절한 데이터가 있지만 DataGrid에 멤버가 표시되지 않는다는 것을 확인했습니다. 그러나

SwitchGrid.ItemsSource = _tempLocation.Switches.Hack(); 

, 엄청난 성능 저하를 만듭니다

public List<T> Hack() 
    { 
     List<T> result = new List<T>(); 
     foreach (T asset in this) 
     { 
      result.Add(asset); 
     } 
     return result; 
    } 

을 지속적으로이 같은 데이터 그리드를 다시 바인딩 : 이상한 것은 내가 AssetHolder 클래스에이 방법을 추가 할 때 작동한다는 것입니다 나는 그것이 그것이 일하는 방식으로 작동해야한다고 생각합니다. 누구가 무슨 일이 일어나는지 알아? DataGrid에서 내 데이터를 표시하지 않는 이유는 무엇입니까?

+0

'GetEnumerator()'권한을 구현 했습니까? 그것을 사용하고 있습니까? 추가 정보 : 필자는 코드 숨김에서 항상'ItemsControl'의'DataContext'를 설정하고 Xmll의'ItemsSource'를'ItemsSource = "{Binding}"로 설정하면 BindingErrors가 더 많이 변경됩니다 출력 창, 그래서 당신은 잘못되고있는 것을 더 잘 진단 할 수 있습니다. – Silvermind

+0

AssetHolder 클래스의 데이터를 채우는 데 드는 비용이 드는 것 같습니다. 이런 식으로 사용하려면 생성자에서 채워야합니다. 또는 ItemsSource를 Hack 메서드에 바인딩 할 수 있지만 반환 유형으로 AssetHolder 을 사용해야합니다. public AssetHolder Hack() {return this; } – JiKra

+0

@Silvermind Dictionary는 IEnumerable을 구현하므로 GetEnumerator 함수를 수정하여 값만 반환했습니다.제대로 작동하는지 확인한 후 위의 게시물에 추가했습니다. – hypehuman

답변

0

편집

I'v 그냥 IDictionary 인터페이스를 구현하고 사전의 개인 변수를 추가했다.

데모 목적으로 인터페이스에서 Add 및 GetEnumerator 만 사용했습니다.

AssetHolder<Person> persons = new AssetHolder<Person>(); 
persons.Add("One", new Person() { FirstName = "Jack" , LastName = "Jobs" , Age = 63 }); 
persons.Add("Two" , new Person() { FirstName = "Peter" , LastName = "Lastname" , Age = 33 }); 
persons.Add("Three" , new Person() { FirstName = "Wally" , LastName = "Breakfast" , Age = 33 }); 
dataGrid1.DataContext = persons; 

XAML : 이 방법은 우리가 TestClass에 사람 사용 우선이 작업을 수행 할 수

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding}" Name="dataGrid1"> 
    <DataGrid.Columns> 
    <DataGridTextColumn Width="1*" Header="FirstName" Binding="{Binding Path=FirstName}"/> 
    </DataGrid.Columns> 
</DataGrid> 

그냥 빨리 테스트를하지만, 이것은 AssetHolder되면, GetEnumerator를() 볼 :

public class AssetHolder<T> : IDictionary<string , T> 
    { 

    Dictionary<string , T> dictionary; 

    public AssetHolder() 
    { 
     dictionary = new Dictionary<string , T>(); 
    } 

    public void Add(string key , T value) 
    { 
     dictionary.Add(key , value); 
    } 

    public bool ContainsKey(string key) 
    { 
     throw new NotImplementedException(); 
    } 

    public ICollection<string> Keys 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public bool Remove(string key) 
    { 
     throw new NotImplementedException(); 
    } 

    public bool TryGetValue(string key , out T value) 
    { 
     throw new NotImplementedException(); 
    } 

    public ICollection<T> Values 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public T this[string key] 
    { 
     get 
     { 
     throw new NotImplementedException(); 
     } 
     set 
     { 
     throw new NotImplementedException(); 
     } 
    } 

    public void Add(KeyValuePair<string , T> item) 
    { 
     throw new NotImplementedException(); 
    } 

    public void Clear() 
    { 
     throw new NotImplementedException(); 
    } 

    public bool Contains(KeyValuePair<string , T> item) 
    { 
     throw new NotImplementedException(); 
    } 

    public void CopyTo(KeyValuePair<string , T>[ ] array , int arrayIndex) 
    { 
     throw new NotImplementedException(); 
    } 

    public int Count 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public bool IsReadOnly 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public bool Remove(KeyValuePair<string , T> item) 
    { 
     throw new NotImplementedException(); 
    } 

    IEnumerator<KeyValuePair<string , T>> IEnumerable<KeyValuePair<string , T>>.GetEnumerator() 
    { 
     throw new NotImplementedException(); 
    } 

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     return dictionary.Values.GetEnumerator(); 
    } 
    } 

사람 클래스 :

public class Person 
    { 
    public string FirstName { get; set; } 
    public string LastName{get;set;} 
    public int Age { get; set; } 
    } 
+0

AssetHolder에서 foreach를 호출하는 C# 코드가 있지만 KeyValuePair에서 AssetObject로 변환 할 수 없다는 것을 알려줍니다. 사용할 GetEnumerator를 어떻게 지정합니까? – hypehuman

+0

하지만 예! 그것은 작동합니다! 왜 원래의 솔루션이 작동하지 않았는 지 잘 모르겠지만이 제품이 제대로 작동하는지 알고 있습니다. – hypehuman

+0

@hypehuman 기뻤습니다. 동의 할 수 있니? :) – Silvermind

0

나는 그것을 알아 냈다! 내 구현이 작동하지 않는 이유는 INotifyCollectionChanged 및 INotifyPropertyChanged 인터페이스가 포함 되었기 때문에 명시 적으로 알려주지 않았기 때문입니다. 구현을 중단했을 때 마술처럼 작동했습니다.