2011-10-10 83 views
13

我最近遇到了一个问题,我有一个ObservableCollection绑定到一个ListView。人们是我写的结构。只要我在绑定之前设置People对象的值,一切似乎都可以正常工作。但是,当我尝试在运行时从GUI设置值时,底层对象似乎并不反映这种变化。为什么绑定到结构不起作用?

我终于通过简单地从一种结构改变人们对类克服了这个问题。没有其他更改是必要的。

有人可以向我解释为什么这是?

+5

你知道结构和类之间的区别? –

回答

21

你结合得到结构的副本,因为结构是按值传递给方法。如果绑定更新了某些内容;在内存中的某个副本正在被修改,因此您的原始对象不会更新。

2

由于结构是按值传递给控制,因此,当您在用户界面的变化,WPF将更改写入回People不同的实例。

其更改为一类,它会工作。

除非你完全理解我建议不使用它的struct的目的。

2

ListView控件是一个ItemsControl并在您填充它是通过声明在XAML或的ItemsSource模式severl ListViewItem的对象,您可以设置绑定的ItemsSource属性

See this Dr. WPF article for a good explanation工程项目无论是在直接模式。无论哪种方式,ListView.Items是一个ItemCollection,它是一个CollectionView,即Items不是您提供给ItemsSource属性的实际集合,而是您提供的集合的标准化副本,它允许框架访问即使IEnumerable没有提供索引器本身,也可以通过索引获得IEnumerable。

由于ListView使用副本,因此当它使用一个Class实例集合时,它可以创建引用的副本,两个引用都指向内存中的同一个对象,以便更改其中一个引用中的值的效果通过其他引用,但是当它使用值类型的结构集合时,它必须创建值的副本,而不是让两个引用指向同一个对象,然后您有两个不同的值类型对象。

1

为所有感兴趣的本主题: 我得到它的运行,用组合框和ObjectDataProvider的。 “ItemsSource”是结构体,但“SelectedItem”写在其他地方。 这就是:

<!--resources--> 
    <ObjectDataProvider x:Key="StructValues" 
         MethodName="GetValues" 
         ObjectType="{x:Type local:MyStruct}"> 
     <ObjectDataProvider.MethodParameters> 
      <x:Type TypeName="local:MyStruct" /> 
     </ObjectDataProvider.MethodParameters> 
    </ObjectDataProvider> 

    <ComboBox Margin="0,5" 
         VerticalAlignment="Center" 
         ItemsSource="{Binding Source={StaticResource StructValues}}"/> 

这是结构的样子:

public struct MyStruct 
{ 
    public const string A = "A"; 
    public const string B = "B"; 
    public const string C = "C"; 

    public static IEnumerable GetValues(Type type) 
    { 
     List<String> retVals = new List<string>(); 
     FieldInfo[] fi = type.GetFields(); 
     foreach (FieldInfo info in fi) 
     { 
      retVals.Add(info.Name); 
     } 
     return retVals; 
    } 
}