Привязка пользовательских структур данных к DataGrid ItemsSource в WPF
Я пытаюсь привязать пользовательский класс к элементу itemssource из WPF DataGrid из C#. Я внедрил IList, но по какой-то причине я не могу получить список, чтобы показать каких-либо участников.
Я устанавливаю свойство ItemsSource в C#, вызывая
dataGridObject.ItemsSource = switchHolderObject
Вот определение для моей стоимости:
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 {}
Причина, по которой у меня есть три класса, состоит в том, чтобы обойти тот факт, что словари в C# не являются ковариантными.
Я проверил, что все мои реализованные методы IList работают должным образом, и список расширяется и имеет соответствующие данные, но DataGrid по-прежнему не показывает членов. Странно то, что он работает, когда я добавляю этот метод в класс AssetHolder:
public List<T> Hack()
{
List<T> result = new List<T>();
foreach (T asset in this)
{
result.Add(asset);
}
return result;
}
и постоянно повторно связывать DataGrid следующим образом:
SwitchGrid.ItemsSource = _tempLocation.Switches.Hack();
Однако это создает огромный удар по производительности, и я чувствую, что все должно работать так, как есть. Кто-нибудь знает, что происходит? Почему DataGrid не показывает мои данные?
2 ответа
редактировать
Я только что реализовал интерфейс IDictionary и добавил приватную переменную Dictionary.
В демонстрационных целях я только использовал Add и GetEnumerator в интерфейсе. Таким образом, мы можем сделать это для начинающих, используя тестовый класс Person:
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:
<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; }
}
Я понял! Причина, по которой моя реализация не сработала, заключается в том, что я включил интерфейсы INotifyCollectionChanged и INotifyPropertyChanged, но я явно не указывал, когда следует уведомлять. Когда я перестал их реализовывать, это волшебным образом сработало!