将自定义数据结构绑定到WPF中的DataGrid ItemsSource

本文关键字:中的 DataGrid ItemsSource WPF 自定义 数据结构 绑定 | 更新日期: 2023-09-27 18:28:15

我正试图从c#将一个自定义类绑定到WPF数据网格的itemsource成员。我实现了IList,但由于某些原因,我无法获得显示任何成员的列表。

我正在通过调用来设置C#中的ItemsSource属性

    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不显示我的数据?

将自定义数据结构绑定到WPF中的DataGrid ItemsSource

编辑

我刚刚实现了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接口,但我没有明确告诉它何时通知。当我停止执行它们时,它神奇地起了作用!