UWP MapControl.Location привязка не работает правильно - PullRequest
1 голос
/ 17 мая 2019

У меня есть приложение UWP с MapControl. Есть список точек, которые отображаются в виде булавок на карте. При щелчке / постукивании элемента рядом с булавкой появляются детали. Однако кажется, что привязка к местоположению не работает должным образом. Элемент управления сведениями часто не отображается до тех пор, пока элемент не будет щелкнут во второй раз или пока карта не будет перемещена / увеличена / изменена каким-либо образом. Когда я отлаживаю, я вижу, что местоположение устанавливается правильно при первом щелчке и не изменяется снова при втором щелчке, поэтому это просто проблема отображения / обновления.

Я создал небольшое демонстрационное приложение, которое показывает поведение здесь . Если вы щелкнете по любому из выводов карты, под ним должен появиться текстовый блок с именем. Он (обычно) работает при первом щелчке, но если вы затем выберите другой штифт, текст (вероятно) изменится, но местоположение не изменится. Если вы щелкнете по другому контакту во второй раз, текстовый блок переместится на него правильно. Это не всегда происходит, но по моим тестам это происходит примерно в 90% случаев. Я также видел еще одну проблему, когда текстовый блок перемещается к правильному выводу, но изначально не выровнен правильно, и снова, когда вы щелкнете снова, он переместится в правильное местоположение.

Я что-то здесь не так делаю? Кто-нибудь сталкивался с этим и знает, как обойти это? Является ли это ошибкой в ​​элементе управления картой, и если да, то где лучше всего сообщать об этих вещах (сколько Microsoft поставила на Github, я нигде не могу найти это).

1 Ответ

1 голос
/ 20 мая 2019

UWP MapControl. Привязка местоположения работает неправильно

Я мог бы воспроизвести вашу проблему, и когда вы нажмете значок карты, а затем увеличите масштаб карты, местоположение будет работать правильно. Причина в том, что элемент управления карты не обновляется после выбора значка карты. Я думаю, что создание новой Grid и привязка с расположением карты DataTemplate вызывают эту проблему. Лучший способ - создать модель IsVisibility для Thing и обработать все привязки данных в DataTemplate. Подробные инструкции приведены в следующем коде.

public class MainViewModel : BaseViewModel
{
    public MainViewModel()
    {
        Things = new ObservableCollection<Thing>
        {
            new Thing("One World Trade Center", 40.712903, -74.013203, SelectMe),
            new Thing("Carlton Centre", -26.205556, 28.046667, SelectMe),
            new Thing("Q1", -28.006111, 153.429444, SelectMe),
            new Thing("Gran Torre Santiago", -33.416944, -70.606667, SelectMe),
            new Thing("Burj Khalifa", 25.197139, 55.274111, SelectMe),
            new Thing("Lakhta Center", 59.987139, 30.177028, SelectMe),
            new Thing("Long Duration Balloon Payload Preparation Buildings", -77.846323, 166.668235, SelectMe),
        };
    }

    public ObservableCollection<Thing> Things { get; }


    private Thing previousThing;
    private void SelectMe(Thing thing)
    {
        if (previousThing != null) previousThing.IsVisibility = false;
        thing.IsVisibility = true;
        previousThing = thing;
    }
}

public class Thing : BaseViewModel
{
    private bool _isVisibility;

    public Thing(string name, double latitude, double longitude, Action<Thing> selector)
    {
        Name = name;
        Location = new Geopoint(new BasicGeoposition { Latitude = latitude, Longitude = longitude });
        SelectMeCommand = new RelayCommand(() => selector(this));
    }

    public string Name { get; set; }
    public Geopoint Location { get; set; }
    public ICommand SelectMeCommand { get; }
    public bool IsVisibility { get => _isVisibility; set => SetProperty(ref _isVisibility, value); }
}

public class VisibleWhenNotNullConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return (bool)value == true ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotSupportedException();
    }
}

Xaml

<map:MapControl HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    <map:MapItemsControl ItemsSource="{x:Bind ViewModel.Things}">
        <map:MapItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Canvas map:MapControl.Location="{Binding Location}">
                        <Path
                            Margin="0"
                            Data="M14-32h-28v27h8l6 5 6-5h8z"
                            Fill="HotPink"
                            IsHitTestVisible="True"
                            Stroke="Black"
                            StrokeThickness="2"
                            >

                            <interactivity:Interaction.Behaviors>
                                <core:EventTriggerBehavior EventName="Tapped">
                                    <core:InvokeCommandAction Command="{Binding SelectMeCommand, Mode=OneWay}" />
                                </core:EventTriggerBehavior>
                            </interactivity:Interaction.Behaviors>
                        </Path>
                        <TextBlock Text="{Binding Name, Mode=OneWay}" 
                                   Visibility="{Binding IsVisibility, Converter={StaticResource VisibleWhenNotNull}, Mode=OneWay}" />
                    </Canvas>
                </Grid>
            </DataTemplate>
        </map:MapItemsControl.ItemTemplate>
    </map:MapItemsControl>
</map:MapControl>
...