问题描述
我正在创建一个Map控件/框架库。我有一个主Map控件,其中可以包含许多LayerControls。我计划使这些LayerControls从ItemsControl继承,以允许用户使用ItemTemplate定义绑定到viewmodel的各种对象,以使其出现在地图上,例如图表,大头针,飞船等。
以下是用法示例:
<map:Map
Scale="{Binding Path=Scale}"
CenterLocation="{Binding Path=CenterLocation}"
MapParametersChangedCommand="{Binding Path=MapParametersChangedCommand}"
MouseDoubleClickCommand="{Binding Path=ChartObjectInfoRequestedCommand}"
UseWaitCursorIcon="{Binding Path=UseWaitCursorIcon}"
>
<map:Map.Layers>
<layers:GeoImageLayer ItemsSource="{Binding Path=WmsLayerviewmodel.WmsMaps}">
<layers:GeoImageLayer.ItemTemplate>
<DataTemplate DataType="{x:Type viewmodels:WmsMapviewmodel}">
<map:GeoImage
Source="{Binding Path=ImageSource}"
ImageOffset="{Binding Path=ImageTransform}"
/>
</DataTemplate>
</layers:GeoImageLayer.ItemTemplate>
</layers:GeoImageLayer>
</map:Map.Layers>
</map:Map>
现在我的问题是: 当从ItemTemplate创建地图特定的控件(图像,图钉,船等)时,我需要访问它以将其订阅某些地图特定的事件,然后取消订阅它们的移除。我希望所有这些都在内部处理,而无需使用viewmodels来处理。在有人问这里的一个问题中,有人建议此解决方案:
protected abstract class BaseGeoLayer : ItemsControl
{
protected BaseGeoLayer()
{
((INotifyCollectionChanged) Items).CollectionChanged += OnCollectionChanged;
}
private void OnCollectionChanged(object sender,NotifyCollectionChangedEventArgs e)
{
// doing stuff
}
}
但是CollectionChanged事件提供了绑定的viewmodel,而不是控件。另外,我还必须考虑在运行时迭代那些子控件的可能性。
是否有不使用VisualTreeHelper的简便方法?
解决方法
我设法通过添加一个冒泡的RoutedEvent来获得创建/删除的控件,该事件由控件的Loaded / Unloaded事件触发。