简体   繁体   English

数据绑定,为什么不起作用? C#BIng地图

[英]Data Binding, why isn't it working? C# BIng Maps

I can't seem to get my head around this pushpin binding and I need some more help. 我似乎无法理解这种图钉绑定,还需要更多帮助。

I have the follow code to parse from XML and split a coordinate string in Lat, Lon and Alt. 我有以下代码可从XML解析,并在Lat,Lon和Alt中拆分坐标字符串。 What I want to do is to display these points as pushpins on my bing maps. 我想要做的是将这些点显示为我的bing地图上的图钉。

I thought that by creating a new object of Geocoordinates in Location I could then bind that to my pushpin location, but nothing is displayed. 我以为,通过在“ Location创建一个新的“地理坐标”对象,我可以将其绑定到我的图钉位置,但是什么也不显示。 Where am I going wrong? 我要去哪里错了?

namespace Pushpins_Itemsource
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {

            InitializeComponent();
        }

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {

            WebClient busStops = new WebClient();
            busStops.DownloadStringCompleted += new DownloadStringCompletedEventHandler(busStops_DownloadStringCompleted);
            busStops.DownloadStringAsync(new Uri("http://www.domain/source.xml"));

        }

        void busStops_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error != null)
                return;



            var busStopInfo = XDocument.Load("Content/BusStops2.xml");

            var Transitresults = from root in busStopInfo.Descendants("Placemark")
                                 let StoplocationE1 = root.Element("Point").Element("coordinates")
                                 let nameE1 = root.Element("name")

                                 select new TransitVariables

                                     (StoplocationE1 == null ? null : StoplocationE1.Value,
                                              nameE1 == null ? null : nameE1.Value);

        }

        // Add properties to your class
        public class TransitVariables
        {
            // Add a constructor:
            public TransitVariables(string stopLocation, string name)
            {
                this.StopLocation = stopLocation;
                this.Name = name;
                if (!string.IsNullOrEmpty(StopLocation))
                {
                    var items = stopLocation.Split(',');
                    this.Lon = double.Parse(items[0]);
                    this.Lat = double.Parse(items[1]);
                    this.Alt = double.Parse(items[2]);
                }
            }

            public string StopLocation { get; set; }
            public string Name { get; set; }
            public double Lat { get; set; }
            public double Lon { get; set; }
            public double Alt { get; set; }

        }

        public class TransitViewModel
        {
            ObservableCollection<TransitVariables> Transitresults ;
            public ObservableCollection<TransitVariables> TransitCollection
            {
                get { return Transitresults; }
            }

        }
    }
}

XAML looks like this. XAML看起来像这样。

<my:Map ZoomLevel="6" Height="500" HorizontalAlignment="Left" Margin="0,6,0,0" CopyrightVisibility="Collapsed" LogoVisibility="Collapsed" Name="Map" VerticalAlignment="Top" Width="456">
    <my:MapItemsControl ItemsSource="{Binding TransitVariables}" Height="494">
        <my:MapItemsControl.ItemTemplate>
            <DataTemplate>
                <my:Pushpin Location="{Binding Location}"  />
            </DataTemplate>
        </my:MapItemsControl.ItemTemplate>
    </my:MapItemsControl>
</my:Map>

From the code you've posted, it looks like the issue is that the ItemsSource for MapsItemsControl is not databound to a collection. 从您发布的代码来看,问题似乎在于MapsItemsControl的ItemsSource没有数据绑定到集合。 It's bound to a type. 它绑定到一个类型。

Okay, Databinding doesn't really work unless you define a DataContext etc. You're sort of mixing and matching paradigms here. 好的,除非您定义了DataContext等,否则数据绑定实际上不会起作用。您在这里混合和匹配了一些范例。 I think it would be good to learn MVVM and Databinding at somepoint, but for now, I think it's okay to just do a quick and dirty approach. 我认为最好在某个时候学习MVVM和数据绑定,但是就目前而言,我认为只需要快速而又肮脏的方法就可以了。

The easiest way to get this working is to just assign the ItemSource. 最简单的方法就是分配ItemSource。

To do this, first name your MapsItemControl, so you can access it in the codebheind. 为此,请先命名您的MapsItemControl,以便您可以在代码管理器中访问它。

<my:Map ZoomLevel="6" Height="500" HorizontalAlignment="Left" Margin="0,6,0,0" CopyrightVisibility="Collapsed" LogoVisibility="Collapsed" Name="Map" VerticalAlignment="Top" Width="456">
<my:MapItemsControl x:Name="RhysMapItems" ItemsSource="{Binding TransitVariables}" Height="494">
    <my:MapItemsControl.ItemTemplate>
        <DataTemplate>
            <my:Pushpin Location="{Binding Location}"  />
        </DataTemplate>
    </my:MapItemsControl.ItemTemplate>
</my:MapItemsControl>

Inside your download string complete handler, you should be able to do this: 在下载字符串完整处理程序中,您应该可以执行以下操作:

    void busStops_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error != null)
            return;



        var busStopInfo = XDocument.Load("Content/BusStops2.xml");

        var Transitresults = from root in busStopInfo.Descendants("Placemark")
                             let StoplocationE1 = root.Element("Point").Element("coordinates")
                             let nameE1 = root.Element("name")

                             select new TransitVariables

                                 (StoplocationE1 == null ? null : StoplocationE1.Value,
                                          nameE1 == null ? null : nameE1.Value);

       // This should bind the itemsource properly
       // Should use Dispatcher actually...see below
       RhysMapItems.ItemsSource = Transitresults.ToList();
    }

Now, the one caveat here, is that it's very likely that your DownloadStringCompleted handler will be invoked on a different thread than the UI thread. 现在,这里需要说明的是,很有可能在与UI线程不同的线程上调用DownloadStringCompleted处理程序。

In which case you'll need to make use of the Dispatcher.BeginInvoke() to modify the ItemSource property. 在这种情况下,您将需要使用Dispatcher.BeginInvoke()来修改ItemSource属性。

this.RootVisual.Dispatcher.BeginInvoke( _=> { RhysMapItems.ItemsSource = Transitresults.ToList();});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM