Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将自定义数据结构绑定到WPF中的DataGrid ItemsSource_C#_Wpf_Binding_Ilist_Itemssource - Fatal编程技术网

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

C# 将自定义数据结构绑定到WPF中的DataGrid ItemsSource,c#,wpf,binding,ilist,itemssource,C#,Wpf,Binding,Ilist,Itemssource,我正在尝试从c#将自定义类绑定到WPF数据网格的itemssource成员。我实现了IList,但由于某些原因,我无法让列表显示任何成员 我正在通过调用 dataGridObject.ItemsSource = switchHolderObject 以下是“我的价值”的定义: public class AssetHolder<T> : Dictionary<string,T>, IList<T>, INotifyCollectionChang

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

我正在通过调用

    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 {}

然而,这造成了巨大的性能冲击,我觉得它应该按现在的方式工作。有人知道发生了什么吗?为什么DataGrid不显示我的数据?

编辑

我刚刚实现了IDictionary接口并添加了Dictionary的私有变量

出于演示目的,我只在接口中使用了Add和GetEnumerator。 通过这种方式,我们可以为初学者使用testclass人员:

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;

我知道了!我的实现不起作用的原因是我包含了INotifyCollectionChanged和INotifyPropertyChanged接口,但我没有明确告诉它何时通知。当我停止实现它们时,它神奇地工作了

您是否实现了
GetEnumerator()
对吗?你在用它吗?另一方面:我总是在code behind中设置
ItemsControl的
DataContext
,并在Xaml中将
ItemsSource
设置为
ItemsSource=“{Binding}”
,这样,输出窗口中出现的绑定错误会有更多的变化,因此可以更好地诊断出问题。我想,这取决于位置,在AssetHolder类中填充数据的位置。您必须在构造函数中填充它,才能像这样使用它。或者,您可以将ItemsSource绑定到Hack方法,但是您应该使用AssetHolder作为返回类型,IMO:public AssetHolder Hack(){return this;}@Silvermind Dictionary实现了IEnumerable,所以我只是修改了GetEnumerator函数以仅返回值。我已经确认它工作正常,并将其添加到上面的帖子中。您是否也通过在GetEnumerator中设置断点来确认它在不被代码访问而仅被Xaml访问时工作正常?这样,如果Xaml触发了绑定,我们现在就可以看到它了,如果您已经指出了这一点,很抱歉,请确保。@Silvermind按照您的建议修改了绑定,但不幸的是,在这种情况下,我仍然没有得到任何绑定错误。我有一些c代码在AssetHolder上调用foreach,但现在它告诉我它不能从KeyValuePair转换到AssetObject。如何指定要使用的GetEnumerator?但是耶!它起作用了!我不知道为什么我的原始解决方案不起作用,但我很高兴这个解决方案起作用了。我做了更多的测试,这就是我学到的:正确发送通知事件(或删除INotify接口)对于在DataGrid中显示任何内容都是必要的。但是仅仅这样做是不够的,因为我的代码仍然返回KeyValuePairs作为foreach结果。您的无类型GetEnumerator方法是将每个结果显示为单个资产对象所必需的。@hypehuman我想实现IList不会覆盖派生字典的GetEnumerator。很高兴它对你有用。
    SwitchGrid.ItemsSource = _tempLocation.Switches.Hack();
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;
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding}" Name="dataGrid1">
  <DataGrid.Columns>
    <DataGridTextColumn Width="1*" Header="FirstName" Binding="{Binding Path=FirstName}"/>
  </DataGrid.Columns>
</DataGrid>
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; }
  }