【问题标题】:Parameterized Constructor for WinRT UserControlWinRT UserControl 的参数化构造函数
【发布时间】:2013-09-01 17:59:15
【问题描述】:

我正在尝试在我的 WinRT 应用程序中为 Bing 地图创建自定义图钉。我的问题是我需要从我的页面中引用实际地图,以便将图标正确固定在我的 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

谢谢

【问题讨论】:

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


    【解决方案1】:

    更新 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 类型的依赖属性,然后您应该将当前地图实例作为该DP 的值传递给&lt;View:GPSIcon ... /&gt;

    简单地说,你需要遵循与Pass parameter to constructor from xaml in Silverlight相同的逻辑

    【讨论】:

    • 谢谢,我试过了,但我无法绑定。我应该为 WinRT 使用什么绑定语法?可视化树是
    • 非常感谢。我等不及 Win8.1 发布了。调试是一场噩梦。我不得不再次重新创建这个应用程序,因为我的自定义控件中的任何内容都不再有效,并且由于某种原因仍然无效。你的样本很有意义。当我构建它时,我会告诉你它是否有效:)
    【解决方案2】:

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

    例如:

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

    【讨论】:

    • 这很棒。非常感谢您的评论
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 2016-03-05
    • 2020-01-23
    • 2013-01-01
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多