WinRT UserControl的参数化构造函数

时间:2013-08-29 10:35:19

标签: windows-8 microsoft-metro winrt-xaml .net-4.5 bing-maps

我正在尝试在WinRT应用程序中为Bing Maps创建自定义Pushpin。我的问题是我需要从我的页面引用实际的Map,以便在我的userControl中正确地固定图标。因此,例如,这是我的DataTemplate,它绑定到地图并适用于正常的图钉。为了使我的自定义userControl正确定位,我需要在userControl中引用父Map。

这是我的XAML:

<m:MapItemsControl x:Name="Pushpinss" ItemsSource="{Binding InventoryItems}">
        <m:MapItemsControl.ItemTemplate>
          <DataTemplate>
            <!-- NORMAL PUSHPIN WORKS -->
            <m:Pushpin>
              <m:MapLayer.Position>
                <m:Location Latitude="{Binding WarehouseLatitude}"
                            Longitude="{Binding WarehouseLongitude}" />
              </m:MapLayer.Position>
            </m:Pushpin>
            <!-- CUSTOM CONTROL DISPLAYS BUT DOES NOT POSITION CORRECTLY BECAUSE I NEED A REFERENCE TO THE MAP-->
            <View:GPSIcon  Latitude="{Binding WarehouseLatitude}"
                           Longitude="{Binding WarehouseLongitude}"
                           Radius="100000"/>
              <x:Arguments>
              </x:Arguments>
          </DataTemplate>
        </m:MapItemsControl.ItemTemplate>
      </m:MapItemsControl>

这是我的自定义控件:

public sealed partial class GPSIcon : UserControl
  {
    private Map _map;
    private const double EARTH_RADIUS_METERS = 6378137;

    public GPSIcon(Map map)
    {
      this.InitializeComponent();

      _map = map;
      _map.ViewChanged += (s, e) =>
      {
        UpdateAccuracyCircle();
      };
    }

    public static readonly DependencyProperty LatitudeProperty =
           DependencyProperty.Register("Latitude", typeof(double), typeof(GPSIcon), new PropertyMetadata(0));

    public static readonly DependencyProperty LongitudeProperty =
        DependencyProperty.Register("Longitude", typeof(double), typeof(GPSIcon), new PropertyMetadata(0));

    public static readonly DependencyProperty RadiusProperty =
       DependencyProperty.Register("Radius", typeof(double), typeof(GPSIcon), new PropertyMetadata(0));

    public double Latitude
    {
      get { return (double)GetValue(LatitudeProperty); }
      set { SetValue(LatitudeProperty, value); }
    }

    public double Longitude
    {
      get { return (double)GetValue(LongitudeProperty); }
      set { SetValue(LongitudeProperty, value); }
    }

    /// <summary>
    /// Radius in Metres
    /// </summary>
    public double Radius
    {
      get { return (double)GetValue(RadiusProperty); }
      set
      {
        SetValue(RadiusProperty, value);
        UpdateAccuracyCircle();
      }
    }

    private void UpdateAccuracyCircle()
    {
      if (_map != null && Radius >= 0)
      {
        double groundResolution = Math.Cos(_map.Center.Latitude * Math.PI / 180) * 2 * Math.PI * EARTH_RADIUS_METERS / (256 * Math.Pow(2, _map.ZoomLevel));
        double pixelRadius = Radius / groundResolution;

        AccuracyCircle.Width = pixelRadius;
        AccuracyCircle.Height = pixelRadius;
        AccuracyCircle.Margin = new Thickness(-pixelRadius / 2, -pixelRadius / 2, 0, 0);
      }
    }
  }

这有可能吗?我也尝试过使用x:Arguments指令,如下所述: http://msdn.microsoft.com/en-us/library/ee795382.aspx

由于

2 个答案:

答案 0 :(得分:0)

更新1

进行以下更改

1)添加空构造函数。

public GPSIcon()
{
    this.InitializeComponent();
}

2)声明类型为Map

的DP
public Map MyMap
{
    get { return (Map)GetValue(MyMapProperty); }
    set { SetValue(MyMapProperty, value); }
}

public static readonly DependencyProperty MyMapProperty =
    DependencyProperty.Register("MyMap", typeof(Map), typeof(GPSIcon), new PropertyMetadata(default(Map), OnMapSet));

private static void OnMapSet(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    _map = ((GPSIcon)(d)).MyMap;
    _map.ViewChanged += (ss, ee) =>
    {
        ((GPSIcon)(d)).UpdateAccuracyCircle();
    };
}

3)在XAML中传递Map这样的对象

<m:Map x:Name="objMap">
    <m:MapItemsControl x:Name="Pushpinss" ItemsSource="{Binding InventoryItems}">
        <m:MapItemsControl.ItemTemplate>
            <DataTemplate>
                <View:GPSIcon Latitude="{Binding WarehouseLatitude}"
                              Longitude="{Binding WarehouseLongitude}"
                              Radius="100000"
                              MyMap="{Binding ElementName=objMap}"/>
            </DataTemplate>
        </m:MapItemsControl.ItemTemplate>
    </m:MapItemsControl>
</m:Map>

再声明一个类型为Map的依赖项属性,然后您应该将当前地图实例作为该<View:GPSIcon ... />

中DP的值传递

简单地说,您需要遵循与Pass parameter to constructor from xaml in Silverlight

相同的逻辑

答案 1 :(得分:0)

要让您的自定义UIElement在地图上正确定位,您可以在代码中执行此操作,只需设置UIElement的位置,就像设置图钉的位置一样。

例如:

<View:GPSIcon Radius="100000">
    <m:MapLayer.Position>
       <m:Location Latitude="{Binding WarehouseLatitude}"
                   Longitude="{Binding WarehouseLongitude}" />
    </m:MapLayer.Position>
</View:GPSIcon>