【发布时间】:2012-08-12 04:53:15
【问题描述】:
我使用的是 Esri 的地图,它提供了一个可以将集合绑定到地图的功能,它可以为绘制和渲染图形点提供所有魔法。它只要求对象具有一些要绑定的属性,如下所示:
<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;最初也绑定正确)。
我的继承实现可能会导致绑定从基本上从单向/双向绑定切换到一次性绑定?我会不会错误地归咎于问题?
编辑:感谢下面的 cmets,我将其范围缩小到 PropertyChange 事件处理程序在设置 IsSelected 时为空。为清楚起见,这里是我在基类中定义 IsSelected 的公共成员的地方:
[DataMember]
public bool IsSelected
{
get { return _IsSelected; }
set
{
if (_IsSelected != value)
{
_IsSelected = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("IsSelected"));
}
}
}
在我的演示应用程序中,一切正常,如果我使用上面的第一组虚拟点(有效),PropertyChanged 不为空,并且 setter 引发 PropertyChanged 事件。
但是,当使用 DataPointSubclass 时,PropertyChanged 始终为 null(但正在触发 setter)。我会在这里遗漏什么?
【问题讨论】:
-
您已将子类集合声明为
ObservableCollection<DataPoint>而不是ObservableCollection<DataPointSubclass>。这是故意的吗? -
我不知道您在这个新子类中创建了哪些属性,但您是否使用 INotifyPropertyChanged 进行了这些属性。
-
@ChrisF 这不是故意的,但我已经检查过了,没有任何区别。感谢您指出了这一点。在我的应用程序中进行调试,在它只处理 DataPoint 的区域中,我可以查看该对象,它仍然标识为 DataPointSubclass,这是我所期望的。我可能会从 CS101 中忘记这种继承吗?
-
@Nathan - 我不这么认为 :) 我只是在检查您的示例中的代码错误是否无意中引入了不同的问题。
-
@Justin 我想你中了大奖。我没有在子类中的任何属性上实现 INotifyPC,因为它们应该只是只读的。 IsSelected 不会被 DataPoint 覆盖,所以我只使用 DataPoint 中的属性,它确实在预期的地方实现了 INotifyPropertyChanged。我注意到但由于某些天真的原因被忽略的有趣的事情是,在集成应用程序中(与我的演示应用程序相反),当我切换 IsSelected 属性时,PropertyChanged 在 DataPoint.IsSelected 的设置器中为空,所以我从不引发 PropertyChanged 事件。
标签: c# wpf silverlight binding esri