WP7 Pushpin tooltip/bubble - windows-phone-7

I am porting an iPhone app to WP7 which contains a map with several markers/pushpins that I get from a webservice (location, icon and title).
I have setup the XAML required to display the map as well as some code for the pushpin:
<phone:PhoneApplicationPage.Resources>
<ControlTemplate x:Key="customPushpin" TargetType="my:Pushpin">
<Image Height="39" Source="Resources/Icons/Pushpins/pinGreen.png" Stretch="Fill" Width="32"/>
</ControlTemplate>
</phone:PhoneApplicationPage.Resources>
<Grid x:Name="LayoutRoot" Background="Transparent">
<my:Map Height="Auto" HorizontalAlignment="Stretch" Margin="0" x:Name="Map"
VerticalAlignment="Stretch" Width="Auto" CredentialsProvider="{Binding CredentialsProvider}"
CopyrightVisibility="Collapsed" LogoVisibility="Collapsed" Center="{Binding Mode=TwoWay, Path=Center}"
ZoomBarVisibility="Visible"
ZoomLevel="{Binding Zoom, Mode=TwoWay}">
<my:MapItemsControl ItemsSource="{Binding Pushpins}">
<my:MapItemsControl.ItemTemplate>
<DataTemplate>
<my:Pushpin MouseLeftButtonUp="Pushpin_MouseLeftButtonUp"
Location="{Binding Location}"
Template="{StaticResource customPushpin}">
</my:Pushpin>
</DataTemplate>
</my:MapItemsControl.ItemTemplate>
</my:MapItemsControl>
</my:Map>
</Grid>
I am looking for a way to add some sort of bubble when the user clicks on the pushpin. I have looked a bit into infoboxes/tooltips but since they work on hover, that's not something I can use for the phone (tap/click).
I am guessing there's no similar control in WP7 that creates a bubble - how could I go about creating something similar?
Thanks in advance,
Alex

You could simply put a square Border inside LayoutRoot with Visibility="Collapsed", then when you click your pushpin you update its content and make it visible.
Just make sure to put it after your map control (otherwise it will be rendered behind the map and will consequently be invisible).

The easiest way to achieve this is to Show/Hide the Content of the Pushpin on Tap instead of MouseLeftButtonUp because of some performance considerations.
void pushPin_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
this.border.Visibility = System.Windows.Visibility.Visible;
//stop the event from going to the parent map control
e.Handled = true;
}
private void map_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
this.border.Visibility = System.Windows.Visibility.Collapsed;
}

You could create a custom popup.
A great video that exaplains how to do this is located here.

Other solution is using the ContextMenu from the Silverlight toolkit for Windows Phone!
Just go to the Coding4Fun page on CodePlex and download it ( it contains the toolkit ) and in your XAML inside the PushPin definition add following:
<map:Pushpin x:Name="currentLocation">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu IsZoomEnabled="False">
<toolkit:MenuItem Header="this is menu item 1" Click="MenuItem_Click" />
<toolkit:MenuItem Header="this is menu item 2" Click="MenuItem_Click" />
<toolkit:MenuItem Header="this is menu item 3" Click="MenuItem_Click" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu></map:Pushpin>
This way, when you tap and hold the pushpin, you'll get the contectmenu!
( good example also found here: example )

Related

when keyboard is show, scrolling is limited

I have a problem with scrolling in windows phone. I have a lot of elements on page so to add ability to scroll I put this on ScrollViewer. Hovewer, when I foucesd on some text block and the keyborad shows up, the scroll in working but it cuts the top and bottom of the page so it's can't be reach by user. Have you had similar problem with your apps and know how to fix this ?
I wil be really grateful for any help
Link to image when I put screenshot with my problem
The picture contains four screenshots:
1) The top of the page
2) The bottom of the page
3) Focus on the first textbox
4) The area on the page which can be reached when focus is set to the first TextBox
The last one picture present the are which can be rached when focus is set to the first textbox. As you can see I can't get to the textboxes below Field 7 when keybord is shown.
What I need is the ability to scroll and to reach all elements when the keybord is shown.
Do you know how to resolve my poblem
It's my xaml code:
<phone:PhoneApplicationPage
x:Class="PhoneApp6.MainPage"
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"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--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="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<ScrollViewer Grid.Row="1" Height="600" Margin="12 0">
<StackPanel>
<StackPanel>
<TextBlock Text="Name 1" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 2" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 3" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 4" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 5" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 6" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 7" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 8" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 9" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 10" />
<TextBox />
</StackPanel>
<Button>Submit</Button>
</StackPanel>
</ScrollViewer>
</Grid>
</phone:PhoneApplicationPage>
This is a known issue and is caused by the SIP changing the viewable area of the screen. The link David Gorden mentioned does help, but you actually need to change the height of the scrollviewer to achieve perfect results. To make things a little more complex WP does not trigger an event for when the SIP is visible! So you need to hook into the GotFocus/LostFocus events.
Edit your scrollviewer so it looks something like this:
<ScrollViewer x:Name="_scrollViewer"
VerticalAlignment="Top"
GotFocus="UIElement_OnGotFocus"
LostFocus="UIElement_OnLostFocus"
... bla bla
Now add the following in the codebehind:
private bool _isHdDevice;
private int _sipHeight;
private double _origHeight;
// Constructor
public MainPage()
{
InitializeComponent();
// todo - cater for landscape mode or sip scopenames that require extra space (predictive text and cut&paste icon)
var deviceWidth = this.ActualWidth;
_isHdDevice = (deviceWidth > 500);
_sipHeight = _isHdDevice ? 540 : 375;
_origHeight = _scrollViewer.Height;
}
private void UIElement_OnGotFocus(object sender, RoutedEventArgs e)
{
double height = this.ActualHeight - _sipHeight - TitlePanel.ActualHeight;
_scrollViewer.Height = height;
// the following lines are crucial otherwise a black band could appear above the SIP
App.Current.RootVisual.RenderTransform = new CompositeTransform();
this.UpdateLayout();
}
private void UIElement_OnLostFocus(object sender, RoutedEventArgs e)
{
_scrollViewer.Height = _origHeight;
}
This is basically resizing the scroll area when the sip (keyboard) is in view. You will need to add more code to cater for things like screen rotation, scopename associated to the textbox, and cut&paste icon if in view. But this will get you going and does the difficult bit.
Please mark as answered if it helped fix the issue.
If I understand this correctly, I was having a similar problem in my own app with an inability to scroll downward to the lowest texboxes while the keyboard is visible. Since I'm not all that clever, I solved it in the following way: a spacer that appears when the keyboard is up and disappears when it's not.
The textbox items for input in my scrollviewer are all in wrappanels, to keep things tidy. Below the last wrap panel, I added another, empty wrap panel, named "spacer" with a height of 120. It is set to visibility.collapsed by default.
As part of the gotfocus event handler for each of the textboxes in the wrap panel, I set spacer to visible. That allows for scrolling all the way to the last wrappanel/textboxes in my scroll viewer while the keyboard is up.
As a part of my lostfocus event handler for each of the textboxes, spacer's visibility is set back to "collapsed." That way, when there's no keyboard up, the scrollviewer doesn't have a big, funky, empty space at the bottom.
This may not be so elegant, but it's easy and works pretty well for me. I have not yet encountered any problems with it, though that doesn't mean there may not be something I've missed.

Font size and weight in Application Bar in Windows Phone

I am trying to duplicate a popup menu shown from a Application bar button (like Reply in the standard Mail app) and I need to know the font size and font weight of the Application bar menu items.
I did som trial and error but I cannot match the size and weight exactly.
Font size: PhoneFontSizeLarge
Font family: PhoneFontFamilySemiLight
Have you tried using a ContextMenu?
Using the following XAML :-
<Grid x:Name="ContentPanel"
Grid.Row="1"
Margin="12,0,12,0">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu IsZoomEnabled="True"
x:Name="ContextMenu">
<toolkit:MenuItem x:Name="Item1"
Header="Item 1"/>
<toolkit:MenuItem x:Name="Item2"
Header="Item 2" />
<toolkit:MenuItem x:Name="Item3"
Header="Item 3" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</Grid>
And the following Application Bar XAML :-
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True"
IsMenuEnabled="True"
x:Name="MyAppBar">
<shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png"
Text="Button 1"
Click="ApplicationBarIconButton_Click"/>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
And the following XMLNS (You need to add the Windows Phone Toolkit via Nuget):-
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
And then finally the following C# :-
private void ApplicationBarIconButton_Click(object sender, EventArgs e)
{
this.ApplicationBar.IsVisible = false;
ContextMenu.IsOpen = true;
}
The ContextMenu pops up in a similar way to the Email reply pop up menu.
Probably:
FontSize="33"
FontWeight="Light"

wp7 binding pushpin List to Maplayer

I want to bind my pushpins (which is a list ) to the My Map`s Maplayer.
There is no such thing "ItemSource" in MapLayers attributes. How can I bind my Pushpin List Data to MapLayer?
<my:Map HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Name="map1" CredentialsProvider="KEY" >
<my:Map.Children>
<my:MapLayer x:Name="pushPinMapLayer" ??Binding what???}">
</my:MapLayer>
</my:Map.Children>
</my:Map>
Please see the link below as it is from a question I asked a while back (which part of it should solve your question)
Binding Pushpins
I think the part that will help you the most is the Xaml (in the Map>ItemsControl element)
<my:Map Height="520" HorizontalAlignment="Left" Margin="6,6,0,0" Name="map1" VerticalAlignment="Top" Width="468" ZoomBarVisibility="Collapsed" ZoomLevel="1" CredentialsProvider="{Binding bingMapsCredentials}" >
<my:MapLayer x:Name="myPushpinLayer">
<my:MapItemsControl Name="Pushpinsss" ItemTemplate="{StaticResource LogoTemplate}" ItemsSource="{Binding PushpinCollection}" >
</my:MapItemsControl>
</my:MapLayer>
</my:Map>
You need to add the MapItemsControl section under your MapLayer

Accessing a ProgressBar within a ListBox of buttons

I want to be able to control when I will show a ProgressBar based on a click event. Normally this would be fine, except that I don't believe I can access the ProgressBar since it is so nested in with this structure.
The following code sample shows the structure I Have
<ListBox Name="AudioListBox" Margin="12,0,0,0" Grid.Row="2" Width="396" HorizontalAlignment="Left" ItemsSource="{Binding Audio}">
<ListBox.ItemTemplate>
<DataTemplate>
<Button BorderThickness="0.0" Click="ChapterPlayerButtonClick" Style="{StaticResource ButtonStyle1}">
<StackPanel Name="ButtonsStackPanel" Margin="0,0,0,17">
<TextBlock Foreground="{Binding ChapterForeground}" Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextLargeStyle}"/>
<ProgressBar x:Name="MyProgressBar" Value="{Binding ChapterProgressPosition}" Visibility="Collapsed"
IsIndeterminate="False" Foreground="{Binding ChapterForeground}" Width="300" Background="Black" HorizontalAlignment="Left">
</ProgressBar>
<TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In this example, I want to be able to change the visbility of this progress bar, as well as bind it to update with a timer I have set up. Unfortunately I can't find a way to turn on the visbility for the progress bar on the button click.
This is where MVVM can really help - you've already got a data binding to your ViewModel presumably from looking at your XAML.
You can send a message to your ViewModel to turn on the progress bar, by changing a IsProgressBarVisible property on your ViewModel.
Then you can bind to this boolean in your ViewModel using a VisibilityValueConverter (see post by Jeff Wilcox at this link for more details).
<ProgressBar
x:Name="MyProgressBar"
Visibility="{Binding IsProgressBarVisible, Converter={StaticResource VisibilityConverter}}"
IsIndeterminate="{Binding IsIndeterminate}"
...
</ProgressBar>
If you want to update bound items within the ItemTemplate you'll need to update the bindings as you can't refer to instances of such items by name. (Because you can't have multiple items with the same name.)
In the Click event handler you can access the viewmodel instance via the sender and manipulate the properties there.
For example, the following will increment the value of the progress bar each time the button is tapped/clicked.
private void ChapterPlayerButtonClick(object sender, RoutedEventArgs e)
{
((sender as FrameworkElement).DataContext as ItemVm).ChapterProgressPosition++;
}
Note that due to a "quirk" of the ProgressBar you'll need to enable TwoWay binding to update the Value via binding.
I'm sure you can work out how to do the rest.
You'll need to bind the Visibility if you want to alter that too.
As an alternative solution I'd replace the button click event with a RelayCommand on the ViewModel itself to simplify the code. You could then put all the logic in the same place and not require all the casting as in the click event handler above.

Why does stackpanel break my pivotviewer?

I have a working pivotviewer with 128 images of cars that I put together myself. I used one of the many tutorials on the web to get it working, and it works well. Then I thought I should decorate the page a bit so I put the grid in which the pv resided inside a bounding stackpanel with a couple of textblocks above it to tell what the collection is. Everything loads fine except the images. Comment out the stackpanel lines and it works perfectly.
Any ideas? How could something so simple fail?
Here is all of the code in MainPage.xaml:
<StackPanel>
<TextBlock
FontSize="24"
HorizontalAlignment="Center"
VerticalAlignment="Top">
Silverlight Pivotviewer Example
</TextBlock>
<TextBlock
FontSize="16"
HorizontalAlignment="Center"
VerticalAlignment="top">
Cool Automobiles
</TextBlock>
<Grid x:Name="LayoutRoot" Background="White">
<pivoter:PivotViewer x:Name="pivotViewer" />
</Grid>
</StackPanel>
Your Grid, "LayoutRoot", is your main layout control. You need to wrap your StackPanel within the Grid control.
Something like this:
<Grid x:Name="LayoutRoot" Background="White"
<StackPanel>
<TextBlock
FontSize="24"
HorizontalAlignment="Center"
VerticalAlignment="Top">
Silverlight Pivotviewer Example />
<TextBlock
FontSize="16"
HorizontalAlignment="Center"
VerticalAlignment="top">
Cool Automobiles />
<pivoter:PivotViewer x:Name="pivotViewer" />
</StackPanel>
</Grid>
After your declaration of your Grid, I would add some rows, i.e. 0, 1, 2. Then I would layout your Stackpanels, PivotViewer, etc.
Hope this helps.
This is a known issue. The StackPanel is a dimensionless element. You need to add Width and Height values to the StackPanel and the PivotViewer will begin working correctly.
This is what we did. We added an event handler to the SizeChanged event on the dialog then sized the PivotViewer. Also after the Initialise or Loaded event call it too...see how you go?
void PivotDialog_SizeChanged( object sender, SizeChangedEventArgs e )
{
SizePivotViewer( );
m_PivotViewer.UpdateLayout( );
}
private void SizePivotViewer( )
{
m_PivotViewer.Width = ActualWidth;
m_PivotViewer.Height = ActualHeight - 20; // Magic number so text will display properly at bottom of Pivot!
}

Resources