Listbox items won't update with binding wp7 - windows-phone-7

I have a listbox, with custom items. Code:
<ListBox Height="600" HorizontalAlignment="Left" Margin="7,6,0,0" Name="friendList" VerticalAlignment="Top" Width="449" ItemsSource="{Binding Friends}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="5,0">
<Image Height="120" HorizontalAlignment="Left" Name="image" Stretch="Fill" VerticalAlignment="Top" Width="120" Source="{Binding ImageUri}" GotFocus="image_GotFocus"/>
<CheckBox Height="78" HorizontalAlignment="Left" Margin="65,63,0,0" x:Name="selectedChckbox" VerticalAlignment="Top" Width="55" IsChecked="{Binding Selected, Mode=TwoWay}"/>
<TextBlock Height="58" HorizontalAlignment="Left" Margin="0,122,0,0" x:Name="nameTextBlck" VerticalAlignment="Top" Text ="{Binding Title}" Width="120" TextWrapping="Wrap" GotFocus="name_GotFocus"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I've created a veiwmodel for the values for binding, and when I click on one item I want to change the checkbox state like so:
friendSelectionViewModel.Friends[_selectFriendContent.friendList.SelectedIndex].Selected = !friendSelectionViewModel.Friends[_selectFriendContent.friendList.SelectedIndex].Selected;
The ViewModel Code:
public class FacebookFriendSelectionViewModel : INotifyPropertyChanged
{
public FacebookFriendSelectionViewModel()
{
Friends = new ObservableCollection<TempFriends>();
}
/// <summary>
/// A collection for MenuItemViewModel objects.
/// </summary>
public ObservableCollection<TempFriends> Friends { get; private set; }
public void AddItem(TempFriends item)
{
Friends.Add(item);
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
public class TempFriends
{
bool _selected;
public string Title { get; set; }
public string ImageUri { get; set; }
public bool Selected {
get
{
return _selected;
}
set
{
_selected = value;
OnPropertyChanged("Selected");
}
}
public string Id { get; set; }
public TempFriends(string title, string imageUir, bool selected, string id)
{
Title = title;
ImageUri = imageUir;
_selected = Selected = selected;
Id = id;
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
But the only way the listbox gets the values updated, if I set the datacontext to null and than assign the viewmodel aggain like so:
_selectFriendContent.DataContext = null;
_selectFriendContent.DataContext = friendSelectionViewModel;
But this takes about 5-10 seconds to refresh the list. I know there is a better solution, I just cant figure out how.
Thanks in advance!

TempFriends class doesn't implement INotifyPropertyChanged as far as I see. Just add public class TempFriends : INotifyPropertyChanged

Related

How to mark the checkbox in repeater in Xamarin.Forms?

I am using checkbox control under repeater to do a radio button functionality, everything seems to be fine but now stuck on how to bind the checkbox when the page loads. I have saved the radio button text whichever was selected and once user come back to page again I want to bin what he has selected last time. Not getting any hint here how to proceed.
<grial:Repeater
x:Name="PP"
SelectionMode="Single"
InitialSelection="Empty"
ItemSize="100"
HorizontalOptions="Start"
ItemsSource="{Binding BlowerPostions}">
<grial:Repeater.ItemTemplate>
<DataTemplate>
<grial:Checkbox
IsChecked="false"
UncheckedBorderColor="Black">
<Label
TextColor="Black"
Text="{ Binding . }"
Margin="8,0" />
</grial:Checkbox>
</DataTemplate>
</grial:Repeater.ItemTemplate>
<grial:Repeater.SelectedItemTemplate>
<DataTemplate>
<grial:Checkbox
IsChecked="true"
UncheckedBorderColor="Black"
InputTransparent="true">
<Label
TextColor="Black"
Text="{ Binding . }"
Margin="8,0" />
</grial:Checkbox>
</DataTemplate>
</grial:Repeater.SelectedItemTemplate>
</grial:Repeater>
View Model :
public class ProductionViewModel : INotifyPropertyChanged
{
public ObservableCollection<BlowerPostion> _blowerPostions;
public ObservableCollection<BlowerPostion> BlowerPostions
{
get => _blowerPostions;
set
{
_blowerPostions = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new
PropertyChangedEventArgs("BlowerPostions"));
}
}
}
public void LoadData()
{
BlowerPostions = new ObservableCollection<BlowerPostion>();
BlowerPostions.Add(new BlowerPostion("Left", 1));
BlowerPostions.Add(new BlowerPostion("Standard", 1));
}
}
public class BlowerPostion
{
public string Text { get; set; }
public int Id { get; set; }
public BlowerPostion(string _text, int _id)
{
Text = _text;
Id = _id;
}
}
I don't use grial:Repeater,but you can refer to the following code which use CheckBox in ListView item.
Item.cs
public class Item
{
public string Name { get; set; }
public string Type { get; set; }
public string Image { get; set; }
//This field indicates whether or not it is selected
public bool isChecked { get; set; }
}
MyViewModel.cs
public class MyViewModel
{
public ObservableCollection<Item> items { get; private set; }
public MyViewModel() {
items = new ObservableCollection<Item>();
items.Add(new Item { Name = "Tomato", Type = "Fruit", Image = "tomato.png", isChecked = true });
items.Add(new Item { Name = "Romaine Lettuce", Type = "Vegetable", Image = "lettuce.png", isChecked = false });
items.Add(new Item { Name = "Zucchini", Type = "Vegetable", Image = "zucchini.png", isChecked = false });
}
}
TestPage1.xaml
<ContentPage.Content>
<ListView x:Name="listview" ItemsSource="{Binding items}" VerticalOptions="FillAndExpand">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Padding="5,0,5,0">
<Label Text="{Binding Name}" HorizontalOptions="StartAndExpand" FontSize="30"/>
<input:CheckBox IsChecked="{Binding isChecked}" Type="Check" Color="White" BoxBackgroundColor="Green" TextColor="White" HeightRequest="40"
CheckChanged="CheckBox_CheckChanged" BindingContext="{Binding .}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
TestPage1.xaml.cs
public partial class TestPage1 : ContentPage
{
public List<Item> selectedItems; // define `selectedItems` as the list of selected items.
public MyViewModel viewModel;
public TestPage1 ()
{
InitializeComponent ();
selectedItems = new List<Item>(); // init the `selectedItems`
viewModel = new MyViewModel();
BindingContext = viewModel;
}
private void CheckBox_CheckChanged(object sender, EventArgs e)
{
var checkbox = (Plugin.InputKit.Shared.Controls.CheckBox)sender;
var ob = checkbox.BindingContext as Item;
if (ob != null)
{
System.Diagnostics.Debug.WriteLine("isChecked = " + ob.isChecked + "<---> Name = " + ob.Name +"<---> Type = " + ob.Type );
if (ob.isChecked)
{
selectedItems.Add(ob);
}
else {
// remove the item
}
}
}
}
Note:
1.add new field isChecked in item model
public bool isChecked { get; set; }
2.Add event CheckChanged for the item.And when we check the CheckBox,we can get the corresponding value isChecked of the CheckBox.
<input:CheckBox IsChecked="{Binding isChecked}" Type="Check" Color="White" BoxBackgroundColor="Green" TextColor="White" HeightRequest="40"
CheckChanged="CheckBox_CheckChanged" BindingContext="{Binding .}" />

ListView Xamarin not Binding when adding item

I Am working with a ListView Control in XF application. My XAML Code looks like this.
<ListView ItemsSource="{Binding RechargeList}" HasUnevenRows="True" VerticalOptions="FillAndExpand">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Path=SelectedParkingID}" TextColor="Red" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
While my code behind looks like
private ObservableCollection<Recharge> _RechargeList = new ObservableCollection<Recharge>();
public ObservableCollection<Recharge> RechargeList
{
get
{
return _RechargeList;
}
set
{
SetProperty(ref _RechargeList, value);
}
}
And I add Items to Collection in DelegateCommand Event
RechargeList.Add(new Recharge() { SelectedParkingIDParkingID = ParkingID, RechargeAmount = double.Parse(RechargeAmount), BalanceAmount = 10 });
However, the Listview fails to refresh. Could some one help me ?
Looks like you have a typo
<TextCell Text="{Binding Path=SelectedParkingID}" TextColor="Red" />
Should be
<TextCell Text="{Binding Path=SelectedParkingIDParkingID }" TextColor="Red" />
based on what your model looks like. If you try to bind to a property that doesn't exist, it fails softly. So you're adding an item, but the TextCell doesn't render since it has no content.
Please try to implement INotifyPropertyChanged interface in your class.
public class Data : INotifyPropertyChanged
{
// boiler-plate
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, string propertyName)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
// props
private string name;
public string Name
{
get { return name; }
set { SetField(ref name, value, "Name"); }
}
}
Each property is then just something like:
private string name;
public string Name
{
get { return name; }
set { SetField(ref name, value, "Name"); }
}

Properly binding list ItemsSource to Linq Table

I'm trying to bind a list box's items source to a Linq Table, the same way you would usually bind a ObservableCollection to it.
I want my list to update with the table when items are removed, added and changed.
I've implemented the INotifyPropertyChanged on the classes of which the table consists. This makes the list update the properties that my items contain, however, in order to update the list when items are added or removed, I have to programmatically rebind the ItemsSource in order to forcefully update the list.
Data context
public class LocalDatabase : DataContext
{
public static string connectionString = "Data Source=isostore:/Database.sdf";
public LocalDatabase() : base(connectionString) { }
public Table<Connection> Connections;
}
Table objects
[Table]
public class Connection : INotifyPropertyChanged
{
private string name;
private string ip;
private ushort port;
[Column(IsPrimaryKey=true, IsDbGenerated=true)]
public int ID { get; set; }
[Column]
public string Name { get { return name; } set { name = value; NotifyPropertyChanged("Name"); } }
[Column]
public string IP { get { return ip; } set { ip = value; NotifyPropertyChanged("IP"); } }
[Column]
public ushort Port { get { return port; } set { port = value; NotifyPropertyChanged("Port"); } }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Target list
<ListBox Name="listBoxConnections" SelectionChanged="listBoxConnections_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Height="78">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="Edit" Click="ConnectionEdit" Tag="{Binding ID}" />
<toolkit:MenuItem Header="Delete" Click="ConnectionDelete" Tag="{Binding ID}" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<TextBlock Text="{Binding Name}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<StackPanel Orientation="Horizontal" Margin="12,-6,12,0">
<TextBlock Text="{Binding IP}" Style="{StaticResource PhoneTextSubtleStyle}" Margin="0" />
<TextBlock Text=":" Margin="2,0,2,0" />
<TextBlock Text="{Binding Port}" Style="{StaticResource PhoneTextSubtleStyle}" Margin="0" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Current binding method
public LocalDatabase Database { get; set; }
public MainPage()
{
InitializeComponent();
Database = new LocalDatabase();
if (!Database.DatabaseExists()) Database.CreateDatabase();
listBoxConnections.ItemsSource = Database.Connections;
DataContext = this;
}
I'm afraid there might be a duplicate somewhere, but I've been searching for the last 2 days, and found no solution or similar question. Probably using the wrong queries.
So, in summary, I want to know the correct way to bind a Table to a list, with it updating upon item removal or addition, and all of that good stuff.
I'm working with Windows Phone 7.1
The best way is to separate your UI code from your DB code. Let your ListBox bind to an ObservableCollection, instead of a Table.
Try reading this:
http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj207023%28v=vs.105%29.aspx

Two Way Binding not working

I am new to two way binding in wp7.The below code does not assign the textbox value to the object automatically and returns null.
Xaml:
<Grid x:Name="ContentPanel" DataContext="{Binding usd}" Grid.Row="1" Margin="14,10,10,-10" >
<TextBox Text="{Binding UserName,Mode=TwoWay}" Name="txt1" Width="200" Height="60" FontSize="20" Margin="128,48,128,499"/>
<TextBox Text="{Binding Password,Mode=TwoWay}" Name="txt2" Width="200" Height="60" FontSize="20" Margin="128,263,128,284"/>
<TextBox Text="{Binding Email,Mode=TwoWay}" Name="txt3" Width="200" Height="60" FontSize="20" Margin="128,159,128,388"/>
<Button Content="Send" FontSize="18" Margin="179,413,170,129"
Click="Button_Click_1" />
</Grid>
Cs:
public class UserLogin:INotifyPropertyChanged
{
private string _username;
private string _pwd;
private string _email;
public string UserName
{
get
{
return _username;
}
set
{
_username = value;
OnPropertyChanged("UserName");
}
}
public string Password
{
get
{
return _pwd;
}
set
{
_pwd = value;
OnPropertyChanged("Password");
}
}
public string Email
{
get
{
return _email;
}
set
{
_email = value;
OnPropertyChanged("Email");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
Instantiation:
public UserLogin usd = null;
In constructor:
usd = new UserLogin();
In Button ClickEvent:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
// ContentPanel.DataContext = usd;
MessageBox.Show(usd.Email);
}
Null reference exception in Message box statement. Thanks..
you can just bind to public properties - so your: DataContext="{Binding usd}" should be wrong because usd is just a field
btw if you set this in your ctor too, an remove the xaml binding it could work
usd = new UserLogin();
ContentPanel.DataContext = usd;
About your control/page (which XAML belongs to it)
it's datacontext should contain a usd property
that property should also notifying property!
of course your control/page's datacontext class also should implement INotifyPropertyChanged
because your usd is not set as a property its just a variable.... do one thing
public UserLogin usd {get;set;}
usd = null;

XML into Pins on a map

I can get the list of Lat and Long in a list as a full string. I now need to be able to use this in the map.
Here is the code to display the map. Currently it's displaying two pins and the location. (xaml)
phone:PhoneApplicationPage
x:Class="BrightonHoveBuses.location"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="696" d:DesignWidth="480"
shell:SystemTray.IsVisible="True" xmlns:my="clr-
namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps">
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="PinItemTemplate">
<my:Pushpin Location="{Binding Location}"
MouseLeftButtonUp="Pushpin_MouseLeftButtonUp_1"
Content="{Binding Id}">
</my:Pushpin>
</DataTemplate>
<ControlTemplate x:Key="pinMyLoc"
TargetType="my:Pushpin">
<Grid Height="26"
Width="26"
Margin="-13,-13,0,0"
RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<CompositeTransform Rotation="-45" />
</Grid.RenderTransform>
<Rectangle Fill="Black"
HorizontalAlignment="Center" Margin="0" Stroke="White" VerticalAlignment="Center" Height="26" Width="26" />
<Ellipse HorizontalAlignment="Center"
Height="16" Margin="0" VerticalAlignment="Center"
Fill="Teal"
Width="16" />
</Grid>
</ControlTemplate>
<DataTemplate x:Key="BusItemTemplate">
<my:Pushpin Location="{Binding Location}"
Name="{Binding Id}"
MouseLeftButtonUp="Pushpin_MouseLeftButtonUp_1">
<Grid>
<StackPanel Orientation="Horizontal">
<Image Source="/Images/1.png" Stretch="None" Width="20" Height="25"/>
</StackPanel>
</Grid>
</my:Pushpin>
</DataTemplate>
<ControlTemplate x:Key="stops"
TargetType="my:Pushpin">
<Grid Height="26"
Width="26"
Margin="-13,-13,0,0"
RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<CompositeTransform Rotation="-45" />
</Grid.RenderTransform>
<Rectangle Fill="Black"
HorizontalAlignment="Center" Margin="0" Stroke="White" VerticalAlignment="Center" Height="26" Width="26" />
<Ellipse HorizontalAlignment="Center"
Height="16" Margin="0" VerticalAlignment="Center"
Fill="Yellow"
Width="16" />
</Grid>
</ControlTemplate>
</phone:PhoneApplicationPage.Resources>
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="BRIGHTON & HOVE BUSES" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="Stop Map" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<!-- This is the coding for the pushpins on the map-->
<Grid Grid.RowSpan="2">
<my:Map Name="map1" CredentialsProvider="Apg4fepCyTYEAQ0UxPKpbIljr_THidmUi7BNRth0JGtGSE0blId5FJSJqYy80kQC" Center="47.620574,-122.34942" Margin="0,139,6,99" Height="458" ZoomLevel="17" LogoVisibility="Visible" CopyrightVisibility="Visible" Loaded="startLocationButton_Click">
<my:Pushpin Location="{Binding CurrentLocation}" Template="{StaticResource pinMyLoc}" Name="myPushPin"/>
<my:MapItemsControl x:Name="MapPins"
ItemsSource="{Binding Pins}"
ItemTemplate="{StaticResource PinItemTemplate}"
/>
</my:Map>
<ListBox Height="87" HorizontalAlignment="Left" Margin="12,603,0,0" Name="listBox1" VerticalAlignment="Top" Width="460" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding latitude}"/>
<TextBlock Text="{Binding NaptanCode}"/>
<TextBlock Text=" "/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar Opacity="1.0" IsMenuEnabled="True" IsVisible="True">
<shell:ApplicationBarIconButton Text="Zoom In" IconUri="/Images/add.png" Click="Buttonplus_Click" />
<shell:ApplicationBarIconButton Text="Zoom Out" IconUri="/Images/minus.png" Click="Buttonminus_Click" />
<shell:ApplicationBarIconButton Text="Me" IconUri="/Images/location.png" Click="ButtonLocation_Click" />
<shell:ApplicationBar.MenuItems>
<shell:ApplicationBarMenuItem Text="Road View" Click="ApplicationBarRoad_Click" />
<shell:ApplicationBarMenuItem Text="Aerial View" Click="ApplicationBarAerial_Click" />
</shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
</phone:PhoneApplicationPage>
Heres the code....
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Device.Location;
using Microsoft.Phone.Shell;
using System.Xml.Serialization;
using System.Xml;
using System.IO.IsolatedStorage;
using Microsoft.Phone.Controls;
using System.Runtime.Serialization.Json;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.Text;
using System.Xml.Linq;
using System.Data.Linq.Mapping;
using System.ComponentModel;
using Microsoft.Phone.Controls.Maps;
using Microsoft.Phone.Controls.Maps.Platform;
namespace BrightonHoveBuses
{
public partial class location : PhoneApplicationPage
{
public location()
{
InitializeComponent();
DataContext = App.ViewMapModel;
MapViewModel view = new MapViewModel();
view.Load();
this.DataContext = view;
WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
Uri url = new Uri("http://www.henry-edwards.co.uk/feed.txt", UriKind.Absolute);
client.DownloadStringAsync(url);
}
GeoCoordinateWatcher watcher;
// Click the event handler for the “Start Location” button.
private void startLocationButton_Click(object sender, RoutedEventArgs e)
{
// The watcher variable was previously declared as type GeoCoordinateWatcher.
if (watcher == null)
{
watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High); // using high accuracy
watcher.MovementThreshold = 20; // use MovementThreshold to ignore noise in the signal
watcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
}
watcher.Start();
} // End of the Start button Click handler.
public class RootContainer
{
[DataMember]
public string StopName { get; set; }
[DataMember]
public string StopId { get; set; }
[DataMember]
public string Stop { get; set; }
[DataMember]
public string RouteId { get; set; }
[DataMember]
public string RouteName { get; set; }
[DataMember]
public string latitude { get; set; }
[DataMember]
public string longitude { get; set; }
[DataMember]
public List<Location> Location { get; set; }
}
void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
{
if ((App.Current as App).locsettings == false)
{
MessageBoxResult m = MessageBox.Show("Do you want to allow this application to use information about your location?", "Use Location", MessageBoxButton.OKCancel);
if (m == MessageBoxResult.OK)
{
watcher.Start();
(App.Current as App).locsettings = true;
}
else if (m == MessageBoxResult.Cancel)
{
watcher.Stop();
(App.Current as App).locsettings = false;
}
}
switch (e.Status)
{
case GeoPositionStatus.Disabled:
// The Location Service is disabled or unsupported.
// Check to see whether the user has disabled the Location Service.
if (watcher.Permission == GeoPositionPermission.Denied)
{
// The user has disabled the Location Service on their device.
MessageBox.Show("Location services must be enabled in your phone settings");
}
else
{
MessageBox.Show("Location services must be enabled");
}
break;
}
}
// Click the event handler for the “Start Location” button.
private void stopLocationButton_Click(object sender, RoutedEventArgs e)
{
watcher.Stop();
}
private GeoCoordinateWatcher loc = null;
public string stopslist;
private void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
myPushPin.Location = e.Position.Location;
map1.SetView(myPushPin.Location, 17.0);
watcher.MovementThreshold = 100;
}
void loc_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
{
if (e.Status == GeoPositionStatus.Ready)
{
map1.SetView(loc.Position.Location, 17.0);
loc.Stop();
}
}
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
if (e.Result != null)
{
XDocument doc = XDocument.Parse(e.Result);
XNamespace ns = "http://schemas.datacontract.org/2004/07/BusExpress.ClassLibrary";
var locations = (from n in doc.Descendants(ns + "ArrayOfStop")
select new RootContainer
{
Location = (from s in n.Elements(ns + "Stop")
select new Location
{
latitude = s.Element(ns + "Lat").Value + " ," + s.Element(ns + "Long").Value,
// longitude = s.Element(ns + "Long").Value,
}).ToList()
}).Single();
// Do something with the list of Route Names in routeNames
listBox1.ItemsSource = locations.Location;
}
}
}
public class MapViewModel : INotifyPropertyChanged
{
public void Load()
{
//Do something here to populate your view collection with pins
Pins.Add(new PinModel() { Id = 2, Name = string.Format("Pin # 2"), Location = new GeoCoordinate(39.932825, -75.168396) });
}
private ObservableCollection<PinModel> _pins = new ObservableCollection<PinModel>();
public ObservableCollection<PinModel> Pins
{
get { return _pins; }
set { _pins = value; RaisePropertyChanged("Pins"); }
}
//Event code to ensure the page updates to model changes.
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private void Pushpin_MouseLeftButtonUp_1(object sender, MouseButtonEventArgs e)
{
Pushpin pin = (Pushpin)sender;
MessageBox.Show(pin.Content.ToString());
}
public class PinModel
{
public string Name { get; set; }
public int Id { get; set; }
public GeoCoordinate Location { get; set; }
}
}
private void ButtonLocation_Click(object sender, EventArgs e)
{
loc = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
//EventHandler for location service status changes
loc.StatusChanged += loc_StatusChanged;
//If the location service is disabled or not supported
if (loc.Status == GeoPositionStatus.Disabled)
{
//Display a message
MessageBox.Show("Location services must be enabled");
return;
}
loc.Start();
}
private void Pushpin_MouseLeftButtonUp_1(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Pushpin pin = (Pushpin)sender;
}
private void Buttonminus_Click(object sender, EventArgs e)
{
double zoom;
zoom = map1.ZoomLevel;
map1.ZoomLevel = --zoom;
}
private void Buttonplus_Click(object sender, EventArgs e)
{
double zoom;
zoom = map1.ZoomLevel;
map1.ZoomLevel = ++zoom;
}
private void ApplicationBarRoad_Click(object sender, EventArgs e)
{
map1.Mode = new RoadMode();
}
private void ApplicationBarAerial_Click(object sender, EventArgs e)
{
map1.Mode = new AerialMode();
}
}
}
EDIT:
public class PinModel : INotifyPropertyChanged
{
public string Name { get; set; }
public int Id { get; set; }
public GeoCoordinate Location { get; set; }
}
EDIT:
I am trying to get all the stops on a bing map. I can get all the locations in a list, this is populated to a list box. This all works.
It's now trying to get all these locations onto the map, also with names.
So i need to do whats on the website - but on the phone - http://www.buses.co.uk/travel/live-bus-times.aspx
Have you checked out the output of your LINQ method? It appears you are only creating one instance in your list. Try this instead of your current parsing method.
var locations = (from n in doc.Descendants(ns + "ArrayOfStop")
select new RootContainer
{
Location = (from s in n.Elements(ns + "Stop")
select new Location
{
latitude = s.Element(ns + "Lat").Value + " ," + s.Element(ns + "Long").Value,
// longitude = s.Element(ns + "Long").Value,
}).ToList()
});
I'm not pretty sure what your question is, but I think your binding with the pushpins is not working?
You have implemented INotifyPropertyChanged on your ObservableCollection. That's not necessary. To make it work, you have to implement it on the PinModel and when you set the Location property than call the RaisePropertyChanged method.
Your PinModel class should look something like below to make your binding work (Allthough it's possible that your binding is working right now, because you bind it once as a whole.)
public class PinModel : INotifyPropertyChanged
{
public string Name { get; set; }
public int Id { get; set; }
private GeoCoordinate _location;
public GeoCoordinate Location
{
get
{
return _location;
}
set
{
_location = value;
RaisePropertyChanged("Location");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Also note that het .Single() method your calling on your linq query is returning a single value instead of a list. Please have a look at the answer by Lance on how to contruct your linq query. (See this link for the .Single() documentation)

Resources