2011-10-10 5 views
13

최근 ObservableCollection을 ListView에 바인딩 한 문제가 발생했습니다. 사람들은 제가 작성한 구조입니다. 바인딩하기 전에 People 객체의 값을 설정하는 한 모든 것이 제대로 작동하는 것처럼 보입니다. 그러나 런타임에 GUI에서 값을 설정하려고하면 기본 객체가 변경 사항을 반영하지 않는 것처럼 보입니다.구조체에 대한 바인딩이 작동하지 않는 이유는 무엇입니까?

필자는 사람들을 구조에서 클래스로 간단히 변경하여이 문제를 극복했습니다. 다른 변경 작업은 필요하지 않았습니다.

누군가이 사실을 설명해 주시겠습니까?

+5

당신은 구조체와 클래스의 차이를 알 수 있습니까? –

답변

21

구조체가 값으로 메소드에 전달되므로 바인딩에 struct 구조체가 생깁니다. 바인딩이 뭔가를 업데이트하면; 어딘가에있는 사본이 수정되고 있으므로 원래 개체가 업데이트되지 않습니다.

2

구조체가 값에 의해 컨트롤에 전달되므로 UI에서 변경하면 WPF는 변경 내용을 People의 다른 인스턴스에 다시 씁니다.

클래스로 변경하면 효과가 있습니다.

struct의 목적을 완전히 이해하지 못하면 사용하지 않는 것이 좋습니다.

2

목록보기는 ItemsControl에 그리고 당신은 당신이 상기 ItemsSource 속성

See this Dr. WPF article for a good explanation에 바인딩 설정 XAML 또는 ItemsSource 모드에서 severl있는 ListViewItem 객체를 선언하여 항목의 채우는 경우 다이렉트 모드에서 작동합니다.

어느 쪽이든, ListView.Items는 CollectionView 인 ItemCollection입니다. 즉 Items는 ItemsSource 속성에 제공하는 실제 모음이 아니라 사용자가 제공 한 모음의 정규화 된 사본입니다. 예를 들어 프레임 워크에서 IEnumerable이 인덱서 자체를 제공하지 않더라도 인덱스로 기본 IEnumerable.

ListView는 복사본을 사용하므로 클래스 인스턴스 컬렉션을 사용하면 참조 복사본을 만들 수 있으므로 두 참조가 메모리의 같은 개체를 가리켜 참조 중 하나의 값이 변경되는 효과가 표시됩니다 다른 참조를 통해,하지만 그것은 가치 유형의 구조체의 컬렉션을 사용하는 경우 동일한 개체를 가리키는 두 개의 참조가 아니라 값의 복사본을 만들어야합니다. 그러면 두 개의 고유 한 값 유형 개체가 생깁니다.

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; 
    } 
} 
관련 문제