ClemensFischer / XAML-Map-Control

XAML Map Control Library
Microsoft Public License
203 stars 59 forks source link

Align the location with the top centre of the Pushpin #71

Closed MartinRobins closed 3 years ago

MartinRobins commented 3 years ago

I am trying to create a pushpin where a triangle points up from the top/centre and the content is centred underneath it, a bit like the following (though to be fair that is unfinished as the arrow is not even centered).

image

I cannot however seem to get the top of the arrow to align correctly to the location specified; it always seems to be pointing a little too high (if you look at the example above, the top of the triangle should align with end of the purple polyline).

I have based it (as much as possible) on the example template in the MainWindow.xaml of your WPF project along with the Generic.xaml in the shared project.

This is what I have tried (simplified as much as possible)...

            <mapControl:MapItemsControl ItemsSource="{Binding Path=DriverLocations}">
                <mapControl:MapItemsControl.ItemContainerStyle>
                    <Style TargetType="{x:Type mapControl:MapItem}">
                        <Setter Property="mapControl:MapPanel.Location"
                                Value="{Binding Path=GeoLocation}" />
                        <Setter Property="HorizontalAlignment"
                                Value="Center" />
                        <Setter Property="HorizontalContentAlignment"
                                Value="Stretch" />
                        <Setter Property="VerticalAlignment"
                                Value="Top" />
                        <Setter Property="VerticalContentAlignment"
                                Value="Stretch" />
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="mapControl:MapItem">
                                    <mapControl:Pushpin Content="{Binding Converter={StaticResource mapWindowPushpinDriverLocationContentConverter}}"
                                                        HorizontalContentAlignment="Center">
                                        <mapControl:Pushpin.Template>
                                            <ControlTemplate TargetType="{x:Type mapControl:Pushpin}">
                                                <Grid>
                                                    <Grid.RowDefinitions>
                                                        <RowDefinition />
                                                        <RowDefinition Height="Auto" />
                                                    </Grid.RowDefinitions>
                                                    <Rectangle Grid.Row="1"
                                                               Fill="{TemplateBinding Background}" />
                                                    <Path HorizontalAlignment="Center"
                                                          Grid.Row="0"
                                                          Fill="{TemplateBinding Background}"
                                                          Data="M 8,0.5 L 0,-16 -8,0.5" />
                                                    <ContentPresenter Grid.Row="1"
                                                                      Content="{TemplateBinding Content}"
                                                                      ContentTemplate="{TemplateBinding ContentTemplate}"
                                                                      ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
                                                                      Margin="{TemplateBinding Padding}"
                                                                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                                                </Grid>
                                            </ControlTemplate>
                                        </mapControl:Pushpin.Template>
                                    </mapControl:Pushpin>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </mapControl:MapItemsControl.ItemContainerStyle>
            </mapControl:MapItemsControl>

For reference, the converter used to provide the content for the pushpin returns a StackPanel with a variable number of children depending on the amount of detail to be displayed.

Is there something that I am missing? I realise that this is not a fault within the control, however I suspect that this is just a property that I have not found (or combination thereof) that will allow me to align correctly.

Thanks,

ClemensFischer commented 3 years ago

Sorry, I can't tell.

Setting VerticalAlignment to Top and HorizontalAlignment to Center works well in the PushpinItemStyle in the sample application.

ClemensFischer commented 3 years ago

You do not seem to need a Pushpin at all. Just put the Grid directly into the MapItem's ControlTemplate.

MartinRobins commented 3 years ago

Thanks, that has helped - I knew there was a combination somewhere. I have simplified it more since writing and combined with your answer I am much closer (I will move this out to a separate control template once it is working and will then apply it to MapItem instead of Pushpin as you suggest)...

            <mapControl:MapItemsControl ItemsSource="{Binding Path=DriverLocations}">
                <mapControl:MapItemsControl.ItemContainerStyle>
                    <Style TargetType="{x:Type mapControl:MapItem}">
                        <Setter Property="mapControl:MapPanel.Location"
                                Value="{Binding Path=GeoLocation}" />
                        <Setter Property="HorizontalAlignment"
                                Value="Center" />
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="mapControl:MapItem">
                                    <mapControl:Pushpin Background="{Binding Converter={StaticResource mapWindowPushpinDriverLocationColorConverter}}"
                                                        Content="{Binding Converter={StaticResource mapWindowPushpinDriverLocationContentConverter}}"
                                                        HorizontalContentAlignment="Center"
                                                        Visibility="{Binding Path=GeoLocation, Converter={StaticResource nullObjectToVisibilityHiddenConverter}}">
                                        <mapControl:Pushpin.Template>
                                            <ControlTemplate TargetType="{x:Type mapControl:Pushpin}">
                                                <Grid>
                                                    <Grid.RowDefinitions>
                                                        <RowDefinition Height="16" />
                                                        <RowDefinition />
                                                        <RowDefinition Height="Auto" />
                                                    </Grid.RowDefinitions>
                                                    <Rectangle Grid.Row="2"
                                                               Fill="{TemplateBinding Background}" />
                                                    <ContentPresenter Grid.Row="2"
                                                                      Content="{TemplateBinding Content}"
                                                                      ContentTemplate="{TemplateBinding ContentTemplate}"
                                                                      ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
                                                                      Margin="{TemplateBinding Padding}"
                                                                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                                                    <Path HorizontalAlignment="Center"
                                                          Grid.Row="1"
                                                          Fill="{TemplateBinding Background}"
                                                          Data="M -8,0 L 0,-16 8,0" />
                                                </Grid>
                                            </ControlTemplate>
                                        </mapControl:Pushpin.Template>
                                    </mapControl:Pushpin>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </mapControl:MapItemsControl.ItemContainerStyle>
            </mapControl:MapItemsControl>

I just need to sort out why my Path is not centring horizontally now (but I know that ones on me).

image