2012-08-15 2 views
1

저는 컬렉션을지도에 바인딩 할 수있는 기능을 제공하는 Esri의지도를 사용하고 있으며 그래픽 포인트를 플로팅하고 렌더링하는 데 필요한 모든 마법을 수행합니다.Silverlight - 상속을 사용할 때 바인딩 문제가 발생했습니다.

<esri:PointDataSource 
     ItemsSource="{Binding Path=PlottedData, Source={StaticResource ViewModel}, Mode=TwoWay}" 
     XCoordinateBinding="{Binding X}" 
     YCoordinateBinding="{Binding Y}" 
     IsSelectedBinding="{Binding IsSelected, Mode=TwoWay}"> 

내 응용 프로그램은 물론, 바로 그 지점보다 더 많은 데이터를 필요로하며, 다른 유형도있다 : 그것은 단지 아래와 같이 객체가 바인딩 몇 가지 특성을 가지고 있어야합니다. 이로 인해 다양한 유형의 모든 DataPoint 하위 클래스를 만든 다음지도를 현명하지 않게 전달합니다.

이 기능은 하위 클래스가없는 데모 응용 프로그램에서 유용하게 사용할 수 있습니다.하지만이를 응용 프로그램에 통합하고 서비스에서 하위 클래스로 데이터를 받기 시작하면 IsSelected 기능이 작동하지 않습니다. 모든 점에서 IsSelected 속성이 예상대로 토글되고 있는지 확인할 수 있지만 토글하면 토큰이지도에 다시 반영되지 않습니다.

var returned = new ObservableCollection<DataPoint>() 
    { 
     new DataPoint(){IsPlottable = true, IsSelected = false, X = 722762, Y = 488253}, 
     new DataPoint(){IsSelected = false, X = 810000, Y = 550000, IsPlottable = true}, 
     new DataPoint(){IsSelected = false, X = 801000, Y = 480000, IsPlottable = true}, 
     new DataPoint(){IsSelected = false, X = 800100, Y = 500000, IsPlottable = true}, 
     new DataPoint(){IsSelected = false, X = 800010, Y = 506000, IsPlottable = true} 
    }; 

다음 작동 : 그들은 모델로 돌아갑니다 후에 나는이 와 서비스 결과를 교체 할 경우, 명확합니다. 그 때 이것을 다음으로 대체하십시오 :

var returned = new ObservableCollection<DataPoint>() 
    { 
     new DataPointSubclass(){IsPlottable = true, IsSelected = false, X = 722762, Y = 488253}, 
     new DataPointSubclass(){IsSelected = false, X = 810000, Y = 550000, IsPlottable = true}, 
     new DataPointSubclass(){IsSelected = true, X = 801000, Y = 480000, IsPlottable = true}, 
     new DataPointSubclass(){IsSelected = false, X = 800100, Y = 500000, IsPlottable = true}, 
     new DataPointSubclass(){IsSelected = true, X = 800010, Y = 506000, IsPlottable = true} 
    }; 

작동이 중지됩니다. 한편, 그 포인트는 정확하게 그려 짐 - 바인딩 된 콜렉션이 생성 될 때 적어도 바인딩이 작동한다는 것을 알았습니다. (위의 서브 클래스가 어떻게 IsSelected = true인지를 알 수 있습니다.

내 상속 구현으로 인해 바인딩이 기본적으로 단방향/양방향 바인딩에서 일회 바인딩으로 전환되는 원인은 무엇입니까? 문제를 잘못 제기 할 수 있습니까?

EDIT : 아래의 의견에 감사드립니다. IsSelected가 설정 될 때마다 PropertyChange 이벤트 핸들러가 null로 축소되었습니다. 명확하게하기 위해, 여기에 내가 기본 클래스에 isSelected의 public 멤버를 정의하는 곳이다 : 모든 작품 내 데모 앱에서

[DataMember] 
    public bool IsSelected 
    { 
     get { return _IsSelected; } 
     set 
     { 
      if (_IsSelected != value) 
      { 
       _IsSelected = value; 
       if (PropertyChanged != null) 
        PropertyChanged(this, new PropertyChangedEventArgs("IsSelected")); 
      } 
     } 
    } 

을, 나는 (이 작업) 위에 더미 점의 첫 번째 세트를 사용하는 경우, PropertyChanged가 null가 아니고, setter가 PropertyChanged 이벤트를 발생시킵니다.

그러나 DataPointSubclass를 사용하는 경우 PropertyChanged는 항상 null이지만 setter가 트리거됩니다. 내가 여기서 무엇을 놓칠 수 있니?

+0

ObservableCollection 가 아니라 'ObservableCollection '으로 서브 클래 싱 된 콜렉션을 선언했습니다. 그게 신중한가요? – ChrisF

+1

이 새 하위 클래스에서 만든 속성을 알지 못하지만 INotifyPropertyChanged를 사용 했습니까? – Justin

+0

@ChrisF는 신중하지는 않았지만 확인한 결과 아무런 차이가 없습니다. 그 점을 지적 해 주셔서 감사합니다. 내 응용 프로그램 전체에서 DataPoint 만 처리하는 영역에서 디버깅 할 때 개체를 볼 수 있으며 여전히 예상대로 DataPointSubclass로 식별됩니다. CS101에서 잊어 버리는 이런 상속에 대해 뭔가가 있습니까? – Nathan

답변

0

내 도구가 들어간 상황 중 하나입니다.

저는 INotifyPropertyChanged 서버 측을 구현하는 기본 클래스를 가지고 있습니다. 내 서비스는 하위 클래스의 객체 컬렉션을 반환합니다. 그것의 하위 클래스부터, 내 클라이언트는 기본 클래스에 대한 액세스가 필요합니다. 이 문제를 해결하기 위해 필자는 실제로 서버 측에 존재하는 파일 클라이언트 측 링크로 추가합니다.심지어는에서 INotifyPropertyChanged를 구현하는 것을 제외하고,

public partial class DataPointSubclass: Application.Server.Data.SharedCode.DataPoint, INotifyPropertyChanged { } 

그것의 꽤 멋진 기능 : 나는 서비스 참조를 업데이트 할 때 그 방법은, 부분 클래스는이 같은 비트 보이는 (references.cs에서) 클라이언트 측 생성 DataPoint에서도이를 구현합니다. 이것은 큰 no-no이며, 모든 문제의 근원이었습니다. 하위 클래스 (최소한 기본 클래스의 속성을 덮어 쓰지 않고)에서 INPC를 다시 구현하면 PropertyChanged는 기본 클래스에서 항상 null이됩니다. 이 경우 기본 클래스가 이미 구현되었는지 확인하지 않고 서비스 참조가 자동으로 INotifyPropertyChanged를 구현합니다.

해결책 : References.svcmap에서이 기능을 비활성화해야합니다. 이 속성을 찾아 거짓로 설정 :

<EnableDataBinding>true</EnableDataBinding> 

당신은 솔루션 탐색기에있는 모든 파일을 표시하고 서버 참조 트리에보고 References.svcmap을 찾을 수 있습니다.

이렇게하면 서비스 참조를 업데이트하여 자동 생성되는 클래스가 INotifyPropertyChanged를 자동으로 구현하지 않습니다. 이 기능을 원하면 수동으로 구현해야합니다.

1

귀하의 서비스 코드는 ObservableCollection<DataPoint>()이므로이 메소드의 반환 유형은 IQueryable<DataPoint> 또는 IEnumerable<DataPoint>입니다.

이렇게하면 알려진 비트 (예 : DataPoint) 만 직렬화하고 다른 멤버는 무시합니다.

예상되는 형식을 올바르게 serialize하기 위해 파생 클래스로 변경해야합니다.

+0

나는 그 생각을하지 못했지만이 문제를 해결하지 못했습니다. 내 포스트를 더 명확하게 편집 할 것입니다. 인위적인 ObservableCollection은 데이터베이스에서 데이터를 수신 (및 무시) 한 후에 모델에 생성됩니다. 즉, 직렬화 된 데이터를 전혀 사용하지 않을 때도이 문제가 발생합니다. 이 서비스는 IEnumerable (DataPointSubclass)을 반환합니다. – Nathan