Карты Nokia для Windows Phone 8: как изменить дизайн кнопки Microsoft.Phone.Maps.Toolkit?

По умолчанию они выглядят так: http://wp.qmatteoq.com/wp-content/uploads/2013/01/map.png. Я бы хотел, чтобы они выглядели как на Nokia Maps, вот так: http://www.themobileindian.com/images/nnews/2012/11/9225/Nokia-Maps.jpg, поэтому они занимают меньше места. И каждый раз, когда я нажимаю на них, они переключаются между значком и описанием.

Допустим, у меня есть два шаблона для кнопки в ресурсах:

<ControlTemplate x:Key="1" TargetType="maptk:Pushpin">
        <Grid x:Name="ContentGrid" Background="Transparent" Margin="-4,0,0,0">
            <StackPanel >
                <Grid Background="Black">
                    <StackPanel Margin="5,5,0,0">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Tap">
                                <cmd:EventToCommand PassEventArgsToCommand="False"
                                                    CommandParameter="{Binding}"
                                                    Command="{Binding ElementName=NearbyMap, Path=DataContext.Pushpin_OnTapCommand}"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                        <TextBlock  Text="{Binding Location}" Foreground="White" />
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding LocationName}" Foreground="White" />
                            <TextBlock Text="-" Foreground="White" Padding="3,0"/>
                            <TextBlock Text="{Binding LocationName}" Foreground="White" />
                        </StackPanel>
                        <TextBlock Text="{Binding LocationName}" Foreground="White" />
                        <TextBlock Text="{Binding LocationName}" Foreground="White" />

                    </StackPanel>
                </Grid>
                <Polygon Fill="Black"  Points="0,0 29,0 0,29" Width="29" Height="29" HorizontalAlignment="Left" />
                <Grid Height="26" Width="26" Margin="-13,-13,0,0" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Left">
                    <Grid.RenderTransform>
                        <CompositeTransform Rotation="-45"/>
                    </Grid.RenderTransform>
                    <Rectangle Fill="Black" HorizontalAlignment="Center" Margin="0" Stroke="White" VerticalAlignment="Center" Height="26" Width="26" />
                    <Ellipse HorizontalAlignment="Center" Height="16" Margin="0" VerticalAlignment="Center" Fill="Green" Width="16" />
                </Grid>
            </StackPanel>
        </Grid>
    </ControlTemplate>

    <ControlTemplate TargetType="maptk:Pushpin"  x:Key="2">
        <Grid Height="26" Width="26" Margin="-13,-13,0,0" RenderTransformOrigin="0.5,0.5" >
            <Grid.RenderTransform>
                <CompositeTransform Rotation="-45"/>
            </Grid.RenderTransform>
            <Rectangle Fill="Black" HorizontalAlignment="Center" Margin="0" Stroke="White" VerticalAlignment="Center" Height="26" Width="26"/>
            <Ellipse HorizontalAlignment="Center" Height="16" Margin="0" VerticalAlignment="Center" Fill="Red" Width="16"/>
        </Grid>
    </ControlTemplate>

и кнопка управления:

<maptk:Pushpin x:Name="PushPins" GeoCoordinate="{Binding Location}" Visibility="Visible" Content="{Binding LocationName}" Template="{StaticResource 2}"/>

Как я могу переключаться между ними с помощью каких-то триггеров или чего-то еще?


person Rares Felecan    schedule 13.05.2013    source источник
comment
Вы придумали хорошее решение для этого? Сам ищу...   -  person Depechie    schedule 22.05.2013


Ответы (5)


@Rares нашел другое решение, которое отлично работает в моем случае...

Таким образом, общая проблема здесь заключается в том, как переключать/изменять дизайн при нажатии на канцелярскую кнопку. Кажется, что когда вы добавляете канцелярские кнопки на карту, они получают свой дизайн из набора инструментов, но вы все равно можете изменить это, установив свойство Style в коде!

Итак, если вы подключаете каждую канцелярскую кнопку к событию касания канцелярской кнопки, вы можете просто сделать следующее в своем коде за страницей XAML:

private void Pushpin_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
    ((Pushpin)sender).Style = Application.Current.Resources["PushpinStyle"] as Style;
}

При условии, что вы создали PushpinStyle внутри словаря ресурсов, который имеет Pushpin как TargetType.

Чтобы иметь возможность сбросить дизайн при нажатии на другую канцелярскую кнопку, я просто держу ссылку на канцелярскую кнопку нажатой и сбрасываю ее стиль перед изменением стиля только что нажатой кнопки!

Отлично работает для меня...

person Depechie    schedule 21.06.2013

Вы можете использовать общий прием, чтобы изменить внешний вид компонентов ТЗ. Это можно использовать практически для всех компонентов ТЗ.

Все компоненты TK имеют стили (определенные в XAML), их нельзя установить с помощью кода. Но вы можете переопределить стиль в своем приложении (имейте в виду, что вы переопределяете стиль в целом, поэтому, если вы измените, например, стили кнопок, все кнопки внутри вашего приложения будут выглядеть так)

Чуть подробнее:

a) Получите источник ТЗ с https://phone.codeplex.com/sourcecontrol/latest.

б) Загляните в Themes/Generic.xaml

c) Рядом с последним элементом вы видите определение стиля для канцелярской кнопки. Начинается с:

<!-- Default Style used for Pushpin -->
    <Style TargetType="maptk:Pushpin">
...

г) Скопируйте этот стиль (или, конечно, вы можете написать его с нуля) и измените стиль так, как вам нравится.

e) Добавьте этот измененный фрагмент кода в свой Application.Resources (например, в раздел Application.Resources в вашем App.xaml)

Имейте в виду, что вам также необходимо ссылаться на правильное пространство имен TK. Для канцелярской кнопки вам необходимо включить:

   xmlns:maptk="clr-namespace:Microsoft.Phone.Maps.Toolkit"

Теперь ваше приложение использует локально переопределенный стиль для канцелярской кнопки.

Кстати: поскольку TK имеет лицензию Ms-PL, имейте в виду, что, вероятно, существуют лицензионные ограничения, если вы берете исходный код из MSFT.

person Marco    schedule 14.05.2013
comment
Это не совсем то, что я ищу. Эти кнопки выглядят так: wp.qmatteoq.com/wp -content/uploads/2013/01/map.png и то, что я ищу, это переключение между ними. Спасибо, в любом случае. - person Rares Felecan; 14.05.2013
comment
Когда вы скопируете стиль, канцелярские кнопки будут выглядеть точно так же. Истинный. Но теперь вы можете изменить его так, как вам нравится, например, вы можете изменить стиль, чтобы они выглядели как второе изображение. Кнопки Nokia (как стиль) не являются частью инструментария (они сделаны Nokia). - person Marco; 14.05.2013
comment
Да, я знаю, что могу изменить их стиль, но это не то, чего я хочу. Я хочу переключаться между ними по событию Tap. - person Rares Felecan; 14.05.2013

Лично мне было проще не использовать набор инструментов для кнопок. Вместо этого я написал пользовательский элемент управления «PushPinUC», который я разработал так, как хотел. UserControl подписывается на событие Tap, поэтому я могу разворачивать/убирать его при нажатии.

Вы можете добавить пользовательские элементы управления в свой элемент управления Map, используя следующий код.

private void BindPushpins(IEnumerable<PushpinIVM> pushpins)
{         
    foreach (var pushpin in pushpins)
    {
        var pushPinUC = new PushpinUC { Pushpin = pushpin };
        var mapOverlay = new MapOverlay { GeoCoordinate = pushpin.Location, Content = pushPinUC };
        var mapLayer = new MapLayer { mapOverlay };
        Map.Layers.Add(mapLayer);
    }                        
}
person vonLochow    schedule 14.05.2013

Я нашел решение: добавить к канцелярским кнопкам только один шаблон управления. Панель стека — это канцелярская кнопка с текстовым полем, а сетка перед панелью стека — это канцелярская кнопка без текстового поля. Панель стека с видимостью свернута. Как вы можете видеть, есть 2 триггера для события касания, где я просто устанавливаю видимость кнопки с текстовым полем как видимую или свернутую. Вы можете использовать любое изображение для канцелярских кнопок.

<ctrls:BaseUserControl.Resources>
    <ControlTemplate x:Key="PushPinTemplate" TargetType="maptk:Pushpin">
        <Grid x:Name="ContentGrid" Background="Transparent" Margin="-4,0,0,0">
            <Grid Height="40" Width="30" Margin="-13,-13,0,0" RenderTransformOrigin="0.5,0.5" >
                <Image Source="/Assets/Images/push1.png" Width="40" Height="40">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="Tap">
                            <cmd:EventToCommand PassEventArgsToCommand="True"
                                                    Command="{Binding ElementName=NearbyMap, Path=DataContext.Rectangle_OnTapCommand}"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </Image>
            </Grid>
            <StackPanel x:Name="DetailsPanel" Visibility="{Binding Path=Visibility}">
                <Grid x:Name="TestGrid" Background="Black">
                    <StackPanel Margin="5,5,0,0">
                        <!--TextBlock tap-->
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Tap">
                                <cmd:EventToCommand PassEventArgsToCommand="True"                                                    
                                                    Command="{Binding ElementName=NearbyMap, Path=DataContext.Pushpin_OnTapCommand}"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                        <TextBlock  Text="{Binding LocationName}" Foreground="White" FontSize="25"/>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding StreetName}" Foreground="White" />
                            <TextBlock Text="{Binding StreetNumber}" Foreground="White" />
                        </StackPanel>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding DistanceToDisplay}" Foreground="White" />
                        </StackPanel>

                    </StackPanel>
                </Grid>
                <Polygon Fill="Black"  Points="0,0 29,0 0,29" Width="29" Height="29" HorizontalAlignment="Left" Visibility="Visible"/>
                <Grid Height="40" Width="30" Margin="-13,-13,0,0" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Left">
                    <Image Source="/Assets/Images/push2.png" Width="40" Height="40">
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Tap">
                                <cmd:EventToCommand PassEventArgsToCommand="True"
                                                    Command="{Binding ElementName=NearbyMap, Path=DataContext.Rectangle_OnTapCommand}"/>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </Image>
                </Grid>
            </StackPanel>
        </Grid>
    </ControlTemplate>
</ctrls:BaseUserControl.Resources>

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <maps:Map x:Name="NearbyMap" 
                  Center="{Binding MapCenter, Mode=TwoWay}"
                  ZoomLevel="15"
                  dp:MapPushPinDependency.ItemsSource="{Binding Path=Locations, Mode=OneWay}"
              >
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Tap">
                <cmd:EventToCommand PassEventArgsToCommand="True"
                                    Command="{Binding ElementName=NearbyMap, Path=DataContext.Map_OnTapCommand}"/>

            </i:EventTrigger>
        </i:Interaction.Triggers>
        <maptk:MapExtensions.Children>
            <maptk:MapItemsControl Name="StoresMapItemsControl">
                <maptk:MapItemsControl.ItemTemplate>
                    <DataTemplate>
                        <maptk:Pushpin x:Name="PushPins" GeoCoordinate="{Binding Location}" Visibility="Visible" Content="{Binding LocationName}" Template="{StaticResource PushPinTemplate}"/>
                    </DataTemplate>
                </maptk:MapItemsControl.ItemTemplate>              
            </maptk:MapItemsControl>
            <maptk:UserLocationMarker x:Name="UserLocationMarker" Visibility="Visible" GeoCoordinate="{Binding MyLocation}"/>
        </maptk:MapExtensions.Children>
    </maps:Map>
</Grid>

person Rares Felecan    schedule 22.05.2013
comment
И как вы переключаетесь обратно в исходное состояние, когда вы нажимаете на другую канцелярскую кнопку? - person Depechie; 23.05.2013

@Depechie

private void RectangleTapAction(GestureEventArgs e)
    {
        var pushpinControl = TryFindParent<Pushpin>(e.OriginalSource as UIElement);
        var pushpin = (pushpinControl as FrameworkElement).DataContext as PushPinModel;

        Locations.Where(t => t.Id != pushpin.Id).ToList().ForEach(t => t.Visibility = Visibility.Collapsed);
        pushpin.Visibility = pushpin.Visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;

        e.Handled = true;

    }

Locations — это ObservableCollection, и есть Linq, где я скрываю текстовое поле для других кнопок. PushPinModel имеет атрибут, представляющий видимость.

person Rares Felecan    schedule 23.05.2013