我最近遇到了一个问题,我将一个ObservableCollection绑定到ListView。人是我写的结构。只要我在绑定之前设置People对象的值,一切似乎都可以正常工作。但是,当我尝试在运行时从GUI设置值时,基础对象似乎不反映更改。
我最终通过简单地将People从一个结构改为一个类来克服这个问题。没有必要进行其他更改。
有人可以向我解释为什么会这样吗?
答案 0 :(得分:22)
您的绑定获取结构的副本,因为结构通过值传递给方法。如果绑定更新某些内容;正在修改某个内存中的副本,因此您的原始对象不会更新。
答案 1 :(得分:2)
因为struct通过值传递给控件,因此当您在UI中进行更改时,WPF会将更改写回到People
的其他实例。
将其更改为一个类,它将起作用。
除非您完全理解struct
我建议不使用它的目的。
答案 2 :(得分:2)
ListView是一个ItemsControl,可以在直接模式下工作,通过在XAML中声明服务器ListViewItem对象或在ItemsSource模式中为ItemsSource属性设置Binding来填充它的项目
See this Dr. WPF article for a good explanation
无论哪种方式,ListView.Items都是一个ItemCollection,它是一个CollectionView,即Items不是你提供给ItemsSource属性的实际集合,而是你提供的集合的规范化副本,它允许框架例如访问底层即使IEnumerable本身不提供索引器,也可以通过索引进行IEn。
由于ListView使用副本,当它使用一组Class实例时,它可以创建引用的副本,两个引用都指向内存中的同一个对象,因此通过其中一个引用更改值的效果是可见的另一个引用,但当它使用值类型的结构集合时,它必须复制值,而不是有两个指向同一对象的引用,那么你有两个不同的值类型对象。
答案 3 :(得分:1)
对所有对此主题感兴趣的人: 我使用Combobox和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;
}
}