我在CodeBehind中创建了一个带有DependencyProperty的UserControl:
public partial class PanelMap_Control : UserControl
{
public ObservableCollection<GMapMarker> Markers
{
get { return (ObservableCollection<GMapMarker>)GetValue(MarkersProperty); }
set { SetValue(MarkersProperty, value); }
}
public static readonly DependencyProperty MarkersProperty = DependencyProperty.Register("Markers", typeof(ObservableCollection<GMapMarker>), typeof(PanelMap_Control), new PropertyMetadata(null));
}
UserControl内部是一个Map,它包含原始的标记集合(不是DependencyProperty)。我需要在UserControl之外使它可用于绑定,所以在构造函数的末尾(一旦设置了地图的标记),我将它设置为控件的DependencyProperty:
public PanelMap_Control()
{
InitializeComponent();
//...map setup...
this.Markers = _map.Markers;
}
然后,UserControl的用户可以绑定如下:
<local:PanelMap_Control Markers="{Binding Path=MapMarkers, Mode=OneWayToSource}"/>
ViewModel中的位置:
public ObservableCollection<GMap.NET.WindowsPresentation.GMapMarker> MapMarkers
{
private get
{
return _mapMarkers;
}
set
{
_mapMarkers = value;
}
}
private ObservableCollection<GMap.NET.WindowsPresentation.GMapMarker> _mapMarkers;
问题是,ViewModel的MapMarkers属性总是以默认值&#34; null结束。&#34;我尝试在PanelMap_Control和ViewModel属性的setter中的SetValue调用上设置断点。调试器首先命中SetValue(),此时_map.Markers有效(非null)。然后它命中ViewModel的setter,值为null - 并且从不反映我传递给SetValue()的实际有效对象。
我确定我只是遗漏了一些简单的东西,但我不能为我的生活找出为什么SetValue(非null)将后跟 ViewModel.MapMarkers.set(null)......再也不会。
(旁注1:我意识到这个DependencyProperty不能用于TwoWay绑定 - 即我无法在UserControl中更新_map.Markers。没关系,我只需要阅读在外面。)
(旁注2:_map.Markers对象永远不会被更改 - 只有集合中的项目 - 所以将DependencyProperty设置为初始集合应该就足够了。)
答案 0 :(得分:1)
请参阅以下问题。
OneWayToSource Binding seems broken in .NET 4.0
OneWayToSource binding resetting target value
OneWayToSource
最初实际上重置了目标属性(标记)。这是设计的。在上面的链接中有关于此的更多信息。
作为一种解决方法,您可以尝试以编程方式设置绑定:
public MainWindow()
{
InitializeComponent();
var vm = new ViewModel();
DataContext = vm;
vm.MapMarkers = control.Markers;
BindingOperations.SetBinding(control, PanelMap_Control.MarkersProperty, new Binding("MapMarkets") { TargetNullValue = control.Markers, FallbackValue = control.Markers });
}
<强> XAML:强>
<local:PanelMap_Control x:Name="control" />