Infobox in WPF Bing Maps - wpf

I've recently started doing some stuff in WPF and I came up with an idea to integrate maps into my application. I tried some stuff with Google Maps, but the capabilities aren't that great, so after a while I gave up on Google Maps in WPF.
A little while later I bumped into Bing Maps. This looked way more promising than Google Maps to use with WPF. I've started playing around with Bing's Maps and the capabilities are great!
However, when I tried to put a pushpin on the map it wasn't immediately clear to me how to add a infobox to the pushpin, when hovering over it. I have found some examples how to do so, but it required procedural code linked to the xaml. I was actually looking for a method without using procedural code.
Is it possible to add a infobox to a pushpin with just xaml? Or does anyone have a good alternative method on how to do so?
There is a tooltip property available though, but I wasn't actually looking for that. I was actually looking for Google Maps' pushpin kind of style (if it is available).

Assuming I understand correctly what you want, I believe the short answer is: Sorry, but it's not possible to add a Google-Maps-style info box to a pushpin with just XAML. However, I'll try to help if I can.
Disclaimer: I've been playing with the Bing Maps control for Silverlight, so hopefully this will be applicable to the WPF version of the control as well.
I imagine that you don't want to use the built-in ToolTip either because you want it to look different (i.e. not just a yellow box with text) or because you want it to not disappear when the user moves the mouse away.
If you just want it to look different, I can offer the following. When I specified a template for my Pushpins, I went ahead and used a re-templated ToolTip and allowed the user to click the pushpin to get more information.
Here's the ToolTip template, defined as a StaticResource, which of course could contain anything you want:
<Style x:Key="MyToolTipStyle" TargetType="ToolTip">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border CornerRadius="5" BorderBrush="Black" BorderThickness="2" Background="#5c87b2">
<ContentPresenter Margin="5">
<ContentPresenter.Content>
<StackPanel Margin="5" MaxWidth="400">
<TextBlock Text="{Binding Name}" FontWeight="Bold" FontSize="16" Foreground="White" TextWrapping="Wrap"/>
<TextBlock Text="{Binding Description}" Foreground="White" TextWrapping="Wrap"/>
</StackPanel>
</ContentPresenter.Content>
</ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And here's where I used it:
<maps:Map>
<maps:MapItemsControl ItemsSource="{Binding SearchResultsManager.Items}">
<maps:MapItemsControl.ItemTemplate>
<DataTemplate>
<maps:Pushpin Location="{Binding Location}" Cursor="Hand" MouseLeftButtonUp="Pushpin_MouseLeftButtonUp">
<ToolTipService.ToolTip>
<ToolTip Style="{StaticResource MyToolTipStyle}" />
</ToolTipService.ToolTip>
</maps:Pushpin>
</DataTemplate>
</maps:MapItemsControl.ItemTemplate>
</maps:MapItemsControl>
</maps:Map>
Then I'd handle when the user clicked on the pushpin to take them to a details area.
private void Pushpin_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
// Get a reference to the object that was clicked.
var clickedSearchResult = (sender as FrameworkElement).DataContext as SearchResultViewModel;
// Do something with it.
}
However, I imagine you want to keep the ToolTip from disappearing, so that the user can click on controls inside it. Unfortunately, I'm not sure there's a simple way to do that. You might have to define your own custom control, which of course would require some C#/VB code.
Perhaps this new control could derive from Pushpin, and it could show the info box content on mouse-over and/or click. You could use the VisualStateManager to keep most of the code in XAML. The C#/VB would just have to provide a dependency property for the content and some overrides to transition between the visual states at the correct times.
I hope that's at least a little bit helpful!

Related

Bing WPF Custom Pushpin Template Overlapping

I am using the Microsoft.Maps.MapControl.WPF dll in c# WPF.
Here is my issue in the picture below:
I use a custom template for the pushpin because I need to display some simple information for it. There is no infobox in the WPF version to my knowledge.
Clustering the pushpins together in one is not an option for me, because the pushpins represent a delivery location which needs to be displayed on the map. Zooming out is not an option for me because there could be a delivery on the other side of town which all need to be displayed by a bounding box including all pushpins.
Here is the code for my custom pushpin template:
<ControlTemplate x:Key="RedPushPinTemplate" TargetType="m:Pushpin">
<Grid >
<TextBlock Name="textBlock1" Text="{TemplateBinding Content}" Canvas.ZIndex="2" Height="75" Width="65" TextWrapping="Wrap" Grid.Column="0" Grid.Row="0" Foreground="Black"></TextBlock>
<Rectangle Width="35" Height="50" Margin="0 35 0 0" Canvas.ZIndex="1">
<Rectangle.Fill >
<ImageBrush ImageSource="pack://application:,,,/Images/redpin.jpg"/>
</Rectangle.Fill>
</Rectangle>
</Grid>
</ControlTemplate>
My question is, is there anyway to write code for the template that detects an overlap and do something nice to display the information for both pins. Better yet, is there an infobox control that someone is aware of that has this functionality built in?
Thank you very much for your time.
Sorry for the late answer.
How many Pushpins do you have? One Possiblity is to compare the List of Items (X&Y Coordinates + Radius) to find out which Pushpins Intersect eachother. Then you can adjust the X value and interate again.
You can also do this on the control level itself attaching a behavior which is constantly looking for pushpins and then see if they intersect.

Why does WP7 ListPicker have different margins and height to TextBox

I have a page in my WP7 app consisting of a TextBox beside a ListPicker. In their default modes, they don't line up properly; the ListPicker has a different padding to the TextBox, and its height is also different.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel Orientation="Horizontal">
<TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top"/>
<toolkit:ListPicker Width="170" ItemsSource="{Binding l}" Style="{StaticResource ListPickerStyle1}" VerticalAlignment="Top"/>
</StackPanel>
</Grid>
Manually tweaking the ListPicker's template to fit in correctly here is tricky and error prone. For example, when its height is adjusted, the caption (i.e. the text of the selected item) is no longer in the centre of the component.
My app is currently failing MS app review because the components are not all the same height.
Is there an easy way for me to set the toolkit:ListPicker to have the same appearance as a TextBox?
The simplest solution will be to take a copy of the the default style and tweak that using Blend to be exactly how you want it to look. This will take a little trial and error to sort out.
You can then use the implicit styling rules to apply it to all ListPickers without having to explicitly set the style on each instance:
<Style x:Key="MyListPickerStyle
TargetType="toolkit:ListPicker>
.... your tweaks here
</Style>
<Style TargetType="toolkit:ListPicker"
BasedOn="{StaticResource MyListPickerStyle}" />
It may be easier to tweak the TextBox Style of course :)

Silverlight databinding to itemsource in parent's parent datacontext

I have a datagrid where in one of the column's header I would like to have a dropdown that filters the data in the grid. The issue being that the datacontext that has the values that would be in this dropdown is in the usercontrol's viewmodel not the datagrids itemssource so the list doesn't seem to be available to the dropdown.
<sdk:DataGridTemplateColumn.HeaderStyle>
<Style TargetType="sdk:DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Assignee" />
<ComboBox x:Name="cboAttorneyHdr" ItemsSource="{Binding Path=Attorneys}"
Margin="3,0,0,0" SelectedItem="{Binding Path=SelectedAttorney, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</sdk:DataGridTemplateColumn.HeaderStyle>
I found an example using relative source for WPF that seems to be asking the same thing but it seems that this doesn't work for Silverlight. I have tried setting this manually in the code behind but the combobox does appear to be available there either!
One way I've found around this problem is to use some helpers as detailed here - it's just one of the possible implementations, but it amounts to emulating the WPF RelativeSourceBinding with AncestorLevel/AncestorType which is still not available in SL4. Or you could try to google 'silverlight combobox in datagrid' for more ways to solve it, I'm sure you can imagine it's a pretty common problem :)
I found this solution which actually ended up working great though it's going to take me a bit to actually understand what the heck it's really doing.
http://weblogs.asp.net/dwahlin/archive/2009/08/20/creating-a-silverlight-datacontext-proxy-to-simplify-data-binding-in-nested-controls.aspx

Double Border with a VisualBrush in WPF

I'm curious if anyone knows of a way to easily get a double border effect in WPF similar to what you see in the selected items in Windows Explorer in Windows 7.
If you look closely, you'll notice that the selected item has a dark border, a lighter, inner-border, and then a gradient background.
Currently, I'm using two borders around an object any time I want to achieve this effect. Doing it that way is ugly syntactically and really muddies my view xaml. Being a web developer at heart I'd like to separate the xaml structure from the style as much as possible. So, I've started putting this into Styles and Content Templates in order to pull it out of my view xaml.
However, I'm curious if there may be a better way to go about this.
I played around for a while using a VisualBrush as a background to try to get the effect. However, I want to be able to apply the background to elements that can be any size and the way the VisualBrush stretched the visual to fit the element background didn't work the way I wanted it to. Essentially, I'd really just like it to stretch the visual the way the WPF layout system would do it.
Any ideas would be greatly appreciated.
--
Dusty
A VisualBrush is probably not what you want to do in this scenario, as it's pretty heavy.
You can solve the problem with some Xaml without nesting borders.
For example,
<Border BorderBrush="#FF00B5C5" BorderThickness="1" CornerRadius="2" Background="White">
<Grid Background="#FF00B5C5" Margin="1">
<Rectangle Fill="#FFA2F2FE" />
<TextBlock Text="This is some text" VerticalAlignment="Center"/>
</Grid>
</Border>
You can, of course, tweak the properties to get the look you need.
EDIT: If you want to create a style, so you can reskin the look-and-feel, you can do something like this:
<Window.Resources>
<Style x:Key="BorderedTextBlock" TargetType="ContentControl">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Border BorderBrush="#FF00B5C5" BorderThickness="1" CornerRadius="2" Background="White">
<Grid Background="#FF00B5C5" Margin="1">
<Rectangle Fill="#FFA2F2FE" />
<TextBlock Text="{Binding}" VerticalAlignment="Center"/>
</Grid>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<ContentControl Style="{StaticResource BorderedTextBlock}" Content="This is some text" Width="200" Height="24"/>
</Grid>
Additionally, turn this into a custom control with all the styling and theming parameters that you need.
Hope that helps,
Sergio

Silverlight Border object not visible when theme applied?

I have a applied one of the Silverlight Toolkit themes to my XAML page, and now for some reason my Border objects don't show up. Is this by design? I've made sure to explicitly state a BorderBrush color that should contrast the theme background, but this does not fix the issue.
In case it helps, the theme I'm using is the BureauBlack theme from the Silverlight Toolkit.
And here is a code snippet of one of my Borders.
<Border VerticalAlignment="Top" Grid.Column="0" Grid.Row="2" Grid.RowSpan="2" BorderBrush="Orange" CornerRadius="10" Margin="0" Height="300">
<StackPanel>
<TextBlock Text="Status Panel" FontSize="20" TextAlignment="Center" />
...
</StackPanel>
</Border>
It looks like when a theme is loaded it loads its own default set of values for most object properties. In this case, the BorderThickness property of the border object defaults to 0. As a result you don't see it.
By explicitly giving the BorderThickness property a value (non-zero ofcourse), I got my border to show up.
In addition, I can recommend Silverlight Spy tool.
One of the feature of Silverlight Spy is to provide a tree of all controls, to display all their properties and to provide an ability to dynamically change them. It greatly decrease time for such problem resolving.
I've used it several times in cases like your.

Resources