Custom pushpins and templating images - xaml

This is probably something simple but I am tearing my hair out at the moment.
I want to display pushpins on a map from a model. So I have created a template for the pushpins
<ControlTemplate x:Key="PushpinTemplate" TargetType="m:Pushpin">
<Grid x:Name="ContentGrid" Width="32" Height="32" Margin="0">
<Image Source="Resources/Pushpins/img.png" Stretch="Fill"/>
</Grid>
</ControlTemplate>
Then use it to a binded collection as follows:
<m:MapLayer x:Name="myPushpinLayer">
<m:MapItemsControl x:Name="myPushpins" ItemsSource="{Binding PushpinCollection}">
<m:MapItemsControl.ItemTemplate>
<DataTemplate>
<m:Pushpin Location="{Binding Location}" Template="{StaticResource PushpinTemplate}" />
</DataTemplate>
</m:MapItemsControl.ItemTemplate>
</m:MapItemsControl>
</m:MapLayer>
But what I want to be able to do is change the image source via a binding but am not sure how I go about doing this. What I was intending to do was to use a converter to change the image depending on an id within the collection if that alters the best way to do this.
Edit:
I got a little further:
<m:MapLayer x:Name="myPushpinLayer">
<m:MapItemsControl x:Name="myPushpins" ItemsSource="{Binding PushpinCollection}">
<m:MapItemsControl.ItemTemplate>
<DataTemplate>
<m:Pushpin Location="{Binding Location}"/>
<m:Pushpin.Template>
<ControlTemplate>
<Grid x:Name="ContentGrid" Width="32" Height="32" Margin="0">
<Image Source="{Binding Type,Converter={StaticResource ImageConverter}}" Stretch="Fill"/>
</Grid>
</ControlTemplate>
</m:Pushpin.Template>
</m:Pushpin>
</DataTemplate>
</m:MapItemsControl.ItemTemplate>
</m:MapItemsControl>
</m:MapLayer>
If I move the pushpin template into the </phone:PhoneApplicationPage.Resources> section then it fails. I am not sure why. I guess now I am trying to get to grips with my uinderstanding of how this all works

Just add the binding to the ControlTemplate
<ControlTemplate x:Key="PushpinTemplate" TargetType="m:Pushpin">
<Grid x:Name="ContentGrid" Width="32" Height="32" Margin="0">
<Image Source="{Binding ImageUri}" Stretch="Fill"/>
</Grid>
</ControlTemplate>
I would recommend a ImageUri (of type Uri) property that reflects what image to display, rather than using a converter. But a converter might also work, the bindings are done in the same way.

Related

Xaml Internal Error error WMC9999: Object reference not set to an instance of an object

This has come up a few times, and I've been struggling with it all day in a UWP app.
My specific issue was that I was using x:Bind inside a ContentTemplate that was inside a DataTemplate:
<DataTemplate x:DataType="IFactionMember">
<Button Command="{x:Bind **Property of IFactionMember**}"> // Good
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid Padding="10,0">
<TextBlock Text="{x:Bind **Property of IFactionMember**}" /> // Bad
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
You cannot do this :(
You could use {Binding} instead for your scenario, for example:
<ListView x:Name="listview" ItemsSource="{x:Bind members}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:IFactionMember">
<Button >
<Button.Template>
<ControlTemplate TargetType="Button" >
<Grid Padding="10,0">
<TextBlock Text="{Binding testtext}" />
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
x:bind lacks some of the features of {Binding}, in x:Bind, Path is rooted at the Page by default, not the DataContext, it seems like if you are using x:bind here, it will try to find the property at the MainPage, so that it will not find the correct property.

How do I create a two column layout using xaml RelativePanel?

I'd really like to use RelativePanel in a UWP app I'm writing, to simplify visual state.
This is what I want
I've tried to achieve this with the following XAML:
<RelativePanel>
<TextBlock x:Name="Title" Height="50" Margin="15" FontSize="24"
RelativePanel.AlignTopWithPanel="True"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True">
</TextBlock>
<TextBox x:Name="Editor" Margin="15" Padding="20" HorizontalAlignment="Stretch"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.Below="Title"
RelativePanel.RightOf="FileList">
</TextBox>
<ListView x:Name="FileList" HorizontalAlignment="Stretch" Margin="15"
RelativePanel.AlignRightWithPanel="True"
RelativePanel.Below="Title">
</ListView>
</RelativePanel>
This isn't working. Editor does not stretch. If I set Editor to RelativePanel.AlignRightWith="FilesList", it stretches past files list and fills the window.
Is there any way to do what I want with RelativePanel? Please don't post suggestions on how to do this in Grid, I can already do that - I want to use RelativePanel in this case
Your Editor control should have -
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.Below="Title"
RelativePanel.LeftOf="FileList"
RelativePanel.AlignBottomWithPanel="True"
Note it should be LeftOf, not RightOf. You will also need AlignBottomWithPanel set to True.

How to make a Stack Panel Visible based on the Tapped Event of a ListView in Windows Phone 8.1?

In my application, I am having a ListView. ListView lists a set of images.
So when the application is running, and when that page is loaded, a list of images are shown.
<ListView ItemsSource="{Binding imageLists}" Background="Red" Tapped="ListView_Tapped">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Background="Green">
<Image Source="{Binding imagePath}" CacheMode="BitmapCache" Stretch="UniformToFill"/>
<StackPanel Name="imageTitle" Visibility="Collapsed" Background="Blue"
HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Foreground="White" Text="Dumy Image Title" FontSize="10"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
As you can see from the code, I have one image & stackpanel inside the listview. And the stackpanel's visibility has been set to collapsed for convenience.
The StackPanel imageTitle resides inside the ListView. Stackpanel contains a TextBlock housing the images name. For now it's dumy text.
On Tapping any image in the list, I am trying to make the stackPanel visible.
The Code Behind:
private void ListView_Tapped(object sender, TappedRoutedEventArgs e)
{
imageTitle.Visibility = Windows.UI.Xaml.Visibility.Visible;
}
Since the stackpanel is inside the listview & I am trying to make it visible on the tap event of the listview, I am not able to acheive the needed result. I know my code is wrong.
If I specify the stackpanel outside the listview, I can make it visible using the code I gave inside the ListView_Tapped function. But even in that case, I need to show the stackpanel (name of the image I clicked) inside the listview item (image I clicked).
Any help??
Can this be achieved using only XAML?
Here's a pure xaml way.
Rather than changing the Visibility of the imageTitle (not a great UX), let's change its Opacity to make its appearing more interesting.
First we need to create a storyboard inside this data template. This storyboard will fade in the imageTitle in 400ms.
And then we drag a ControlStoryboard behavior from Expression Blend's Asset panel onto the top level Grid. Basically we want the storyboard to fire off when this Grid is tapped.
Please see below code for reference.
<DataTemplate x:Key="GroupTemplate">
<Grid Background="Green">
<Grid.Resources>
<Storyboard x:Name="ShowImageTitleStoryboard">
<DoubleAnimation Duration="0:0:0.4" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="imageTitle"/>
</Storyboard>
</Grid.Resources>
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Tapped">
<Media:ControlStoryboardAction Storyboard="{StaticResource ShowImageTitleStoryboard}"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
<Image Source="{Binding Image}" CacheMode="BitmapCache" Stretch="UniformToFill"/>
<StackPanel x:Name="imageTitle" Background="Blue"
HorizontalAlignment="Center" VerticalAlignment="Center" Opacity="0">
<TextBlock Foreground="White" Text="Dumy Image Title" FontSize="10"/>
</StackPanel>
</Grid>
</DataTemplate>
Apart from JustinXL's answer it can also be done by using ChangePropertyAction. Also pure XAML:
<DataTemplate>
<Grid Background="Green">
<Image Source="{Binding imagePath}" CacheMode="BitmapCache" Stretch="UniformToFill">
<i:Interaction.Behaviors>
<ic:EventTriggerBehavior EventName="Tapped">
<ic:ChangePropertyAction TargetObject="{Binding ElementName=imageTitle}" PropertyName="Visibility" Value="Visible"/>
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
</Image>
<StackPanel Name="imageTitle" Visibility="Collapsed" Background="Blue"
HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Foreground="White" Text="Dumy Image Title" FontSize="10"/>
</StackPanel>
</Grid>
</DataTemplate>
It's just another way to change a property - JustinXL's answer will provide nice animation with opacity, which will look much better.
I dunno why you specifically want to handle the scenario using XAML. For the Microsoft's recommended MVVM model you should bind a property to your element field and then you can write a converter for the same to return back "Visible" or "Collapse".

Adding A Background Image In XAML

I am very new to XAML code, but I want to try and code a personal program. I have started with XAML but anything I add does not show up. Here is my code:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button Content="Home" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="7,725,0,0" Height="36" Width="91" BorderBrush="Orange" Foreground="Orange" FontFamily="BankGothic Md Bt"/>
<Image HorizontalAlignment="Left" Height="768" VerticalAlignment="Top" Width="1366" Source="C:/Users/Flynn/Desktop/BG.gif" Visibility="Visible"/>
</Grid>
</Page>
The button nor the image is showing up when I run the program. Can someone point me in the right direction? Thanks for your help!
To set a background to a grid, just keep your image in Images folder and add this code inside grid
<Grid.Background>
<ImageBrush Stretch="Fill" ImageSource="..\Images\background.jpg" AlignmentY="Top" AlignmentX="Center"/>
</Grid.Background>
Please try this code.It works
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Button Content="Home" HorizontalAlignment="Left" VerticalAlignment="Top" Height="36" Width="91" BorderBrush="Orange" Foreground="Orange" FontFamily="BankGothic Md Bt"/>
<Image Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Center" Source="Images/super.jpg"/>
</Grid>
You should define the background property like this
You must add in to App.xaml (for color resource)
<Application.Resources>
<SolidColorBrush x:Key="ApplicationPageBackgroundThemeBrush" Color="BlueViolet"/>
</Application.Resources>
Image source have to be in your solution (application)

How do I add text inside a shape in XAML

I am working on a Metro App using C++ and XAML. I want to create a polygon shape and add text inside it.
At first I thought of defining my own Controltemplate and apply it to Textblock but unfortunately it does not understand TargetType = "TextBlock".
Secondly, I thought of inheriting the Polygon class and see if I can do anything there but that class is sealed.
Any ideas on how to achieve this?
In WPF XAML you could do something simple like this:
<Grid Width="60" Height="100">
<Ellipse Fill="Yellow"/>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="Hello"/>
</Grid>
To get text in the centre of a yellow ellipse.
I'm guessing something that simple will work on WinRT.
You can use something like this with ContentControl or so many other controls:
<ContentControl Width="200" Height="100" Content="Something">
<ContentControl.Template>
<ControlTemplate>
<Grid>
<Ellipse Fill="Red"/>
<TextBlock Text="{Binding Content,RelativeSource={RelativeSource FindAncestor,AncestorType=ContentControl}}"
TextWrapping="Wrap"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>