我有一个自定义行为,允许我将MapControl
范围(边界框)绑定到ViewModel;它的工作原理是,只要地图的LoadingStatusChanged
事件触发并设置DependencyProperty
的值,就会计算地图的范围。这很好 - 当地图被平移或缩放时,ViewModel中的绑定属性会更新。
但我还希望能够从ViewModel设置地图范围并相应地进行地图平移/缩放。我可以在依赖项属性更改时调用TrySetViewBoundsAsync
,但问题是知道依赖项属性更改是源于计算映射的范围,还是来自在ViewModel中设置属性。如果是来自计算范围,它将改变地图的范围,这将再次触发更改的事件,并在无限循环中消失。
我通过添加IsFromEvent
属性并在每次响应LoadingStatusChanged
事件计算范围时将其设置为true来解决此问题。这可以防止无限循环,但这种方法似乎......关闭。它让我觉得自己很害羞而且不是非常安全。
所以...有更好的方法吗?可以以某种方式设置DP而不会导致PropertyChanged事件触发吗?或者我只是想过这个?
public class ExtentBehavior : DependencyObject, IBehavior
{
public DependencyObject AssociatedObject { get; private set; }
public void Attach(Windows.UI.Xaml.DependencyObject associatedObject)
{
AssociatedObject = associatedObject;
var mapControl = associatedObject as MapControl;
mapControl.LoadingStatusChanged += MapLoadingStatusChanged;
}
public static readonly DependencyProperty ExtentProperty =
DependencyProperty.Register("Extent", typeof(MapControl), typeof(ExtentBehavior), new PropertyMetadata(null, OnExtentPropertyChanged));
public GeoboundingBox Extent
{
get { return GetValue(ExtentProperty) as GeoboundingBox; }
set { SetValue(ExtentProperty, value); }
}
private async static void OnExtentPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var behavior = dependencyObject as ExtentBehavior;
var mapControl = behavior.AssociatedObject as MapControl;
if (!behavior.IsFromEvent)
{
var result = await mapControl.TrySetViewBoundsAsync(behavior.Extent, null, MapAnimationKind.Default);
}
behavior.IsFromEvent = false;
}
private bool IsFromEvent { get; set; }
private void MapLoadingStatusChanged(MapControl sender, object args)
{
if (sender.LoadingStatus == MapLoadingStatus.Loaded)
{
IsFromEvent = true;
Extent = GetBounds(sender);
}
}
private GeoboundingBox GetBounds(MapControl mapControl)
{
// code omitted
}
}
答案 0 :(得分:0)
无法询问是谁更改了依赖项属性的值。话虽如此,有一种方法;你可以走回调用堆栈/跟踪。 XAML开发人员多年来一直试图在没有文字字符串的情况下动态提高propertychanged。您的解决方案比使用这样的反射更优雅1000%。
有时我们必须解决解决方案的问题 - 有时解决方案不是基础框架的一部分。您的解决方案可能会感觉有点off
,但它解决问题的事实本身就是一种信用。此外,我不认为"线程安全"在这种情况下是一个相关问题,因为所有XAML都在UI线程上。有意义吗?
祝你好运。