2011-10-10 19 views
13

最近ListViewにObservableCollectionがバインドされている問題が発生しました。人々は私が書いた構造です。バインディングする前にPeopleオブジェクトの値を設定する限り、すべてが正常に機能しているようです。しかし、実行時にGUIから値を設定しようとすると、元のオブジェクトは変更を反映していないように見えます。構造体へのバインディングが機能しないのはなぜですか?

私は最終的に人を構造からクラスに変更するだけでこの問題を克服しました。それ以外の変更は必要ありませんでした。

これはなぜ私に説明していただけますか?

+5

あなたは構造体とクラスの違いを知っていますか? –

答えて

21

構造体は値によってメソッドに渡されるので、バインディングにはstructのコピーが得られます。バインディングが何かを更新する場合。メモリ内のコピーがどこかで変更されているため、あなたの元のオブジェクトは更新されません。

2

構造体は値によってコントロールに渡されるため、UIで変更を加えるとWPFは変更を別のインスタンスPeopleに書き戻します。

これをクラスに変更すると動作します。

structの目的を完全に理解していない限り、私はそれを使用しないことをお勧めします。

2

のListViewはItemsControlにであり、あなたはそれがXAMLでか、ItemsSourceプロパティにバインド

See this Dr. WPF article for a good explanationを設定するのItemsSourceモードでseverlのListViewItemオブジェクトを宣言する商品です移入ダイレクトモードのいずれかで動作します。

どちらの方法でも、ListView.ItemsはCollectionViewであるItemCollectionです。つまりItemsはItemsSourceプロパティに提供する実際のコレクションではなく、指定したコレクションの正規化されたコピーです。 IEnumerableがインデクサ自体を提供しないにも関わらず、インデックスによって基になるIEnumerable。

ListViewはコピーを使用するため、クラスインスタンスのコレクションを使用して参照のコピーを作成すると、両方の参照がメモリ内の同じオブジェクトをポイントするため、参照の1つの値の変更の影響が見えます同じオブジェクトを指す2つの参照を持つのではなく、値のコピーを作成する必要がある値型の構造体のコレクションを使用している場合、2つの異なる値型オブジェクトがあります。

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; 
    } 
} 
関連する問題