My ultimate goal is to have pushpins with custom images on a Bing Map in a WP7 app. I have created a control template and a map with a pushpin. Right now, I can get the default pushpins to show up, but nothing shows when I try to template it. Here's what I have right now:
<phone:PhoneApplicationPage.Resources>
<ControlTemplate x:Key="PushpinControlTemplate" TargetType="my:Pushpin">
<Image Source="/Images/Pins/pin.png" />
</ControlTemplate>
</phone:PhoneApplicationPage.Resources>
<my:Map Name="mapMain" CredentialsProvider="CredKey">
<my:Pushpin/>
</my:Map>
If I apply the PushpinControl template nothing shows up:
<my:Pushpin Template="{StaticResource BoaPushpinControlTemplate}" />
If I remove the template, it shows the default black shape.
I must be doing my template incorrectly, but I don't know what the problem is. Can I not have an image in the ControlTemplate?
If you arent using ItemSource binding on the Map then use simple content control approach
<maps:Pushpin Location="{Binding Location}">
<Image Source="/Images/Pins/pin.png" />
</maps:Pushpin>
Or if you dynamically populating the push-pins use the below approach
<maps:Map x:Name="map" >
<maps:MapItemsControl ItemsSource="{Binding Collection}">
<maps:MapItemsControl.ItemTemplate>
<DataTemplate>
<maps:Pushpin Location="{Binding Location}">
<Image Source="/Images/Pins/pin.png" />
</maps:Pushpin>
</DataTemplate>
</maps:MapItemsControl.ItemTemplate>
</maps:MapItemsControl>
</maps:Map>
Even though this thread is a little bit old I'm going to post my suggestion:
Try out this link Working with Pushpins, it is working for me (create a new style and use it in pushpin declaration)
(App.xaml, do not forget the namespace!)
xmlns:m="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps" >
<Application.Resources>
<Style TargetType="m:Pushpin" x:Key="PushpinStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="m:Pushpin">
<Image Width="24" Height="24" Source="path_to_pic" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
(in the xaml there the map is)
<Grid x:Name="LayoutRoot" Background="Transparent">
<m:Map x:Name="Map" Mode="Aerial"
CredentialsProvider="CredKey">
<m:MapItemsControl x:Name="Content">
<m:MapItemsControl.ItemTemplate>
<DataTemplate>
<m:Pushpin Location="{Binding Location}" Style="{StaticResource PushpinStyle}" />
</DataTemplate>
</m:MapItemsControl.ItemTemplate>
</m:MapItemsControl>
</m:Map>
</Grid>
If this isn't working check if the Build Action of your picture is set to content.
Took me a while to figure this out, so i hope i could help someone, despite the fact that this thread is old. ;)
Related
I have a 'feedback' button which has this strange border:
So I searched online for some solutions and modified the control template, and I got this:
Control Template code:
<Button.Template>
<ControlTemplate TargetType="Button">
<ContentPresenter Content="{TemplateBinding Content}" />
</ControlTemplate>
</Button.Template>
So even after modifying the control template - I am getting a strange brown border. Help would be appreciated regarding this.
Button code:
<Button Grid.Row="3"
Grid.Column="2"
Grid.RowSpan="2"
Style="{StaticResource IconStyleBase}"
Name="Feedback_Button">
<Button.Template>
<ControlTemplate TargetType="Button">
<ContentPresenter Content="{TemplateBinding Content}" />
</ControlTemplate>
</Button.Template>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="218*" />
<RowDefinition Height="68*" />
</Grid.RowDefinitions>
<!--Icon-->
<Button Background="#3767B0"
Style="{StaticResource IconStyleContent}">
<!--Content-->
<Button.ContentTemplate>
<DataTemplate>
<Viewbox>
<TextBlock Padding="55"></TextBlock>
</Viewbox>
</DataTemplate>
</Button.ContentTemplate>
</Button>
<!--Icon Text-->
<Button Background="#FF2D5BA0"
Style="{StaticResource IconStyleSubBase}">
<!--Content-->
<Button.ContentTemplate>
<DataTemplate>
<Viewbox>
<TextBlock Padding="15">Feedback</TextBlock>
</Viewbox>
</DataTemplate>
</Button.ContentTemplate>
</Button>
</Grid>
</Button>
A DataTemplate defines the appearance of the the items that you set as Content of a button, but the button itself as a container has a default style and control template that defines how it looks like, along with its different states like mouse-over or pressed. That is where the border comes from.
You can try to create a style that sets the BorderThickness to 0 and apply it on each of your buttons. This approach works for control templates that bind the border thickness from their templated parent.
<Style x:Key="BorderlessButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="BorderThickness" Value="0"/>
</Style>
If this does not work or you want adapt the appearance of your buttons in detail, you have to extract and adapt the button style and control template.
Your custom control template does not work, because you did not apply it to the inner buttons and you should remove Content="{TemplateBinding Content}". Nevertheless, your button control template does not define any control states, so it will not be responsive at all.
You should copy the control template for Button from here, or extract it manually via Blend or Visual Studio. Then you can remove or the Border within it, change its thickness or color, so it will disappear. Moreover, you can adapt its various states to fit your desired style.
A notice on your design. It do not think that it is a good idea to nest buttons. Your control should either be a single button or a panel with two buttons in it, but that also only makes sense if they execute different actions in a related context, like split buttons do.
I'm trying to create a Toolbar control that can group selected buttons with a border and a label. If there is already a built-in control that will do this then I could use that instead of building a UserControl.
If not, then what I'm wanting to build is a UserControl that would allow me to enter one-to-many of my ImageButton UserControls and set a GroupLabel text like below. Can this be done in WPF?
<User_Controls:ToolbarGroup GroupLabel="Entity">
<User_Controls:ImageButton ButtonText="Entity Setup"/>
<User_Controls:ImageButton ButtonText="New Entity"/>
</User_Controls:ToolbarGroup>
PS: I would post an image but this quirky forum won't allow me to post an image.
If i have got you correctly then I think you can achieve this way also, and on mouse eneter and leave event you can do the button click job.
for setting text you can use a grid and a label inside it to set the text, and Image buttons below it.
<UserControl x:Class="ABC.View.Oats"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Image Source="{Binding Image}" Stretch="Fill"/>
</Grid>
</UserControl>
I think what you're looking for is a GroupBox, it has a header property where you can set the label.
Something like this:
<GroupBox Width="300" Height="100">
<GroupBox.Header>
<Label>Text</Label>
</GroupBox.Header>
<StackPanel>
<Button Content="Button"/>
<Button Content="Button"/>
<Button Content="Button"/>
</StackPanel>
</GroupBox>
I would also recommend using the groupbox, it seems to be doing exactly what you want it to do and it looks neat. Here's some examples on how to use them: http://www.dotnetperls.com/groupbox-wpf
On the other hand, if you believe the groupbox is not sufficient, you could create a control that inherits from the groupbox and you could extend it and add whatever you need to it. It would look like this:
public class customGroupBox: GroupBox{
....Add whatever you need here
}
Thanks for the replies. I tried the GroupBox and it's not the layout we want because we want the label underneath the buttons and centered. I never could find a way to add a collection to the UserControl. Maybe I didn't ask the question right by calling it a container. The code below will work, but it's not elegant. I wanted something that would wrap the layout in a UserControl and allow me to add a variable number of buttons to each toolbar group.
<StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0">
<Border Background="GhostWhite" BorderBrush="Gainsboro" BorderThickness="1">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<User_Controls:ImageButton ButtonText="New 1"/>
<User_Controls:ImageButton ButtonText="New 2"/>
<User_Controls:ImageButton ButtonText="New 3"/>
</StackPanel>
<Label HorizontalAlignment="Center" Content="Group 1"/>
</StackPanel>
</Border>
<Border Background="GhostWhite" BorderBrush="Gainsboro" BorderThickness="1">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<User_Controls:ImageButton ButtonText="New 4"/>
</StackPanel>
<Label HorizontalAlignment="Center" Content="Group 2"/>
</StackPanel>
</Border>
</StackPanel>
One way to accomplish this is with a custom styled ItemsControl.
You can then reuse it and just bind it to different data.
Please forgive me, this is hand-typed...
In your resources...
<Style x:Key="ToolbarGroupItemsControlStyle" TargetType="ItemsControl">
...
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ItemsControl">
<Grid>
... XAML to form your group with a binding to the
... group name
<ItemsPresenter/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="ToolbarGroupItemTemplate">
<Grid>
... XAML and binding for each toolbar group item ...
</Grid>
</DataTemplate>
In your XAML...
<ItemsControl
Style="{DynamicResource ToolbarGroupItemsControlStyle}"
ItemsSource="{Binding ToolbarGroupItems}"
ItemTemplate="{DynamicResource ToolbarGroupItemTemplate"/>
If your resources above are at the application level, then you can place the ItemsControl above on any Window/UserControl you want.
Your ItemsSource will need to be a collection of a custom type you create that has bindings for the button text, etc.
I hope this is helpful.
I've used WPF and IDataErrorInfo in the past apps to display errors to the user via a controltemplate by putting an image in the adorner and adding a tooltip to the image like this;
<Style x:Key="textStyle" TargetType="TextBox">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<Border BorderBrush="Orange"
BorderThickness="2"
CornerRadius="4"
SnapsToDevicePixels="True">
<Border.Effect>
<DropShadowEffect BlurRadius="10"
ShadowDepth="0"
Color="Orange" />
</Border.Effect>
<DockPanel>
<Image Width="16"
Height="16"
Margin="-20,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
RenderOptions.BitmapScalingMode="HighQuality"
Source="{StaticResource imgError}"
ToolTip="{Binding ElementName=adornedElement,
Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}"
ToolTipService.ShowDuration="30000" />
<AdornedElementPlaceholder Name="adornedElement" />
</DockPanel>
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
With the appropriate implementation of IDataErrorInfo in the ViewModel and setting Textbox in the view accordingly the image and tooltip are shown;
<TextBox Name="txt"
Grid.Column="0"
Height="40"
Background="Aqua"
Style="{StaticResource textStyle}"
Text="{Binding Path=Text,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True}" />
<TextBlock Grid.Column="1"
Height="40"
Background="AliceBlue"
Text="{Binding ElementName=txt,
Path=(Validation.Errors).CurrentItem.ErrorContent}" />
The above code displays correctly in my previous apps and shows the error in the image tooltip as confirmed by the Textblock.
However, in my current app which is built using Prism I can't get the Image to display. The TextBlock updates correctly and I can set the error to the TextBox tooltip via a style trigger without any issue. The problem is I can't seem to get the image (or anything else) to display in the Adorner. The Image is not shown and border is not changed.
The difference between previous apps and this is that the view is in a Region in a ContentControl and I've used dependency injection to inject the viewmodel into the view constructor and set the DataContext.
I can't figure out why this doesn't work when it did previously. I think I may need to include an AdornerDecorator somewhere but I'm perplexed as to where having tried it in a few places without success. Any ideas how I can ensure the Adorner is shown?
Used an AdornerDecorator to wrap the element containing the texbox and all works fine.
I'm currently using this extension to set specific events which handle data in the ViewModel... Example:
<swi:Interaction.Triggers>
<swi:EventTrigger EventName="Click">
<esi:CallDataMethod Method="SaveRevision_Clicked"/>
</swi:EventTrigger>
</swi:Interaction.Triggers>
Where esi and swi are:
xmlns:esi="clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity"
xmlns:swi="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
But what I want to set an event for a TreeViewItem? I don't have direct access to them, do I?
EDIT: I'm actually using ItemContainerStyle,
<Style x:Key="FolderView" TargetType="{x:Type TreeViewItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<HierarchicalDataTemplate ItemsSource="{Binding Children}" >
<StackPanel Orientation="Horizontal">
<Image Name="img"
Width="20"
Height="20"
Stretch="UniformToFill"
Source="Images/hdicon.png"/>
<TextBlock Text="{Binding FolderName}" Margin="5,0" />
</StackPanel>
</HierarchicalDataTemplate>
</Setter.Value>
</Setter>
</Style>
But I can't place my event in there. Where should I put these lines?
<swi:Interaction.Triggers>
<swi:EventTrigger EventName="Expanded">
<esi:CallDataMethod Method="Expand"/>
</swi:EventTrigger>
</swi:Interaction.Triggers>
Thanks in advance!
You need to use TreeView.ItemContainerStyle to achive this, here are couple of implementations which may help:
Strange Behaviour WPF TreeView ItemContainerStyle and ItemTemplate
WPF Double Click TreeviewItem Child Node
I'm working on a WP7 demo app and have gotten my popup working with static resources wich I earlier had problems with. Now when this is out of the way i got a new bug wich regards my use of Bing Maps.
When using bing maps in my default WP7 Silverlight pages (panorama or regual) the maps show up fine, but when using a bing map in my static resource layout the map itself is just showing up black.
Controls around the map such as the navigation pane with zoom and map modes display fine and the bing map logo and distance reference line also show up fine but the map images is just plain black (transparent since the background of my popup is black).
Anyone who encountered this before?
I came up on post where this problem occured in the default silverlight pages (some signed assemblies bug) so I tried their fix with unsigned assemblies but then my WP7 app did not start.
*Edit
My popup resource XAML code looks like this.
<ResourceDictionary xmlns:my="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Skanetrafiken.Controls;assembly=Skanetrafiken.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
>
<Style TargetType="local:MapRouteDialog">
<Setter Property="Background" Value="{StaticResource PhoneChromeBrush}"/>
<Setter Property="Width" Value="480"/>
<Setter Property="Height" Value="800"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MapRouteDialog">
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}" Margin="0, 0, 0, 0">
<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,30,0,40">
<TextBlock x:Name="DialogTitle" Text="MY DIALOG TITLE" Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
<my:Map x:Name="RouteMap" Grid.Row="1" Margin="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" NavigationVisibility="Visible">
<Button x:Name="ButtonZoomIn" HorizontalAlignment="Left" VerticalAlignment="Top" Height="56" Width="56" Margin="8,180,0,0" BorderBrush="{x:Null}" Foreground="{x:Null}">
<Button.Background>
<ImageBrush ImageSource="/Skanetrafiken.Controls;component/images/Zoom_In.png" />
</Button.Background>
</Button>
<Button x:Name="ButtonZoomOut" HorizontalAlignment="Left" VerticalAlignment="Top" Height="56" Width="56" Margin="8,260,0,0" BorderBrush="{x:Null}" Foreground="{x:Null}">
<Button.Background>
<ImageBrush ImageSource="/Skanetrafiken.Controls;component/images/Zoom_Out.png" />
</Button.Background>
</Button>
<my:MapLayer Name="RouteLines"></my:MapLayer>
<my:MapItemsControl Name="PushPins"/>
</my:Map>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
no code needed for displaying a map, this xaml works in a standard silverlight WP7 page but not when used in resources like this. When used like this the map image/content will be missing and transparent.
Sorry to be a party pooper, but you might be affected by this nugget of truth:
http://blogs.claritycon.com/blogs/kevin_marshall/
Content in a popup is not hardware
accelerated. If you try to animate
stuff in a popup, it will be slow. If
you need to mimic popup like
functionality, consider re-templating
the PhoneApplicationFrame to wrap the
contentpresenter in a grid and place a
contentpresenter below it to act as a
placeholder for a fake popup. You can
then write a popup manager to insert
whatever child you previously had in a
popup into the content presenter/fake
popup. This allows you to have better
perf on the content in the popup and
you can have smoother animations for
sliding / flipping the popup into
place.
Adding the popup to the Visual Tree (any child control of your page) should solve the problem.