Поведение MapsItemControl и ObservableCollection - PullRequest
0 голосов
/ 15 января 2019

У меня есть следующий шаблон MapsItemControl, чтобы показать много выводов / элементов на карте. Он привязан к ObservableCollection, потому что я хочу, чтобы они были показаны или скрыты с помощью различных параметров. Это код XAML для MapsItemControl внутри элемента управления Map.

<Maps:MapItemsControl x:Name="mapSpotsItems">
    <Maps:MapItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel x:Name="spotPin" Visibility="{Binding isVisible}"
                        Maps:MapControl.Location="{Binding geopoint}" Tag="{Binding ID}" ToolTipService.ToolTip="{Binding Description}" 
                        RenderTransformOrigin="0.5,1" Tapped="spotPin_Tapped">


                 <StackPanel Orientation="Horizontal" Tag="{Binding ID}">
                     <Grid>
                         <!-- Karratua -->
                         <Rectangle Width="25" Height="25" Fill="{StaticResource DarkGreyThemeColor}" Opacity="0.5"/>
                         <Rectangle Width="25" Height="25" Fill="{x:Null}" Stroke="Black" StrokeThickness="0.5" />
                         <!-- Borobila -->
                         <Image Source="{Binding MainTag}" Height="20" Width="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                      </Grid>

                      <StackPanel Background="{StaticResource DarkGrey75ThemeColor}">
                          <TextBlock Text="{Binding Title}" Margin="5,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="50" MaxLines="2" TextWrapping="Wrap" TextTrimming="CharacterEllipsis" Style="{StaticResource BaseTextBlockStyle}" FontSize="11" Foreground="{StaticResource LightGreyThemeColor}" LineHeight="11"/>
                       </StackPanel>
                   </StackPanel>

                   <Rectangle Width="2" Height="10" Fill="Black" StrokeThickness="0" StrokeEndLineCap="Triangle" />

               </StackPanel>
           </DataTemplate>
       </Maps:MapItemsControl.ItemTemplate>
   </Maps:MapItemsControl>

И это Модель данных :

        private class SpotElement
    {
        public int ID { get; set; }
        public Visibility isVisible { get; set; }
        public bool isSelected { get; set; }

        public Visibility score1 { get; set; }
        public Visibility score2 { get; set; }
        public Visibility score3 { get; set; }
        public int Rating { get; set; }

        public string Title { get; set; }
        public string Description { get; set; }

        public double Distance { get; set; }

        public Geopoint geopoint { get; set; }
        public double Latitude { get; set; }
        public double Longitude { get; set; }
        public double Altitude { get; set; }

        public DateTime[] Date { get; set; }

        public globalVars.TagImageURL[] Tag { get; set; }
        public string MainTag { get; set; }

        public Point NormalizedAnchorPoint { get; set; }

        public string grouping { get; set; }
    }

    private ObservableCollection<SpotElement> allSpots;

У меня есть некоторые проблемы, связанные с этим.

  1. Когда я изменяю ObservableCollection, например значение isVisible (чтобы показать или скрыть с помощью выбора в фильтре, элементы не изменились вообще. Это код, который фильтрует видимость элементов:

    /// <summary>
    /// Filtratu egiten ditu erakutsi beharreko spot-ak
    /// </summary>
    private void FilterSpots()
    {
        foreach (var item in allSpots)
        {
            // TODO: tag-ak falta dira filtratzeko
            bool visibilitySelected = true;
            if (Filter.showOnlySelected)
            {
                visibilitySelected = (item.isSelected == true);
            }
            bool visibilityBool = visibilitySelected && item.Rating >= Filter.minRating;
            Visibility visible = GlobalFunc.BoolToVisibility(visibilityBool);
    
            if (visible != item.isVisible)
            {
                item.isVisible = visible;
            }
    
            //Debug.WriteLine(item.Title + ": Rating {0} >= {1}? " + item.isVisible, item.Rating, Filter.minRating);
        }
        //mapSpotsItems.ItemsSource = null;
        //mapSpotsItems.ItemsSource = allSpots;
    }
    

    Закомментированная строка отладки - это та, которую я использовал для проверки правильности значений в ObservableCollection (allSpots). Следующие 2 строки (mapSpotsItems.ItemsSource = null; и mapSpotsItems.ItemsSource = allSpots;) - единственный режим, в котором у меня есть элементы для фильтрации. Я думаю, что это худший способ сделать это, но во время тестирования это работало, несмотря на время, необходимое, чтобы спрятаться и показать снова (иногда, например, 20 секунд, когда карта не работает должным образом). Вот как я проверяю, является ли значение истинным, тогда видимость видна, а если ложным, то свернулась.

        /// <summary>
    /// Booleanetik Visibility-ra itzultzen du. True bada pasatako booleana, Visible izango da; Collapsed bestela.
    /// </summary>
    /// <param name="testBool"></param>
    /// <returns></returns>
    public static Visibility BoolToVisibility(bool testBool)
    {
        if (testBool) return Visibility.Visible;
        else return Visibility.Collapsed;
    }
    
  2. Создание предметов (у меня как 2000-3000 предметов) очень медленное и при панорамировании карты движение с видимой задержкой. Есть ли способ сделать его более приятным и отзывчивым?

  3. И последний вопрос, несмотря на то, что я установил RenderTransformOrigin = "0.5,1", как если бы я установил RenderTransformOrigin = "0.0,0.0", визуализированный с верхней левой границы. enter image description here. Если вы посмотрите на изображение, элемент отображается с красной точки, а не с синей, как и должно быть.

Спасибо!

1 Ответ

0 голосов
/ 15 января 2019

Когда я изменяю ObservableCollection, например значение isVisible (чтобы показать или скрыть с помощью выбора в фильтре, элементы не изменились вообще.

Visibility - это Enum, но не bool. Вам нужно сделать BoolToVisConverter для xaml.

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

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return value is Visibility && (Visibility)value == Visibility.Visible; 
    }
}

Создание предметов (у меня как 2000-3000 предметов) очень медленное и при панорамировании карты движение с видимой задержкой. Есть ли способ сделать его более приятным и отзывчивым?

MapItemsControl отличается от ListView и GridView, он не поддерживает виртуализацию пользовательского интерфейса . Для производительности, пожалуйста, избегайте рендеринга слишком большого количества элементов одновременно

И последний вопрос, несмотря на то, что я установил RenderTransformOrigin = "0.5,1", как если бы я установил RenderTransformOrigin = "0.0,0.0", визуализированный с верхней левой границы.

RenderTransformOrigin свойство не используется для установки AnchorPoint. Для настройки правильного макета вы можете установить NormalizedAnchorPoint.

<maps:MapItemsControl.ItemTemplate>
    <DataTemplate>
        <Button x:Name="mapItemButton" Click="mapItemButton_Click" Background="Transparent">
            <StackPanel>
                <Border Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
                    <TextBlock Text="{Binding DisplayName}"/>
                </Border>
                <Image Source="{Binding ImageSourceUri}"
                           maps:MapControl.NormalizedAnchorPoint="{Binding NormalizedAnchorPoint}"
                           maps:MapControl.Location="{Binding Location}">
                    <Image.Transitions>
                        <TransitionCollection>
                            <EntranceThemeTransition/>
                        </TransitionCollection>
                    </Image.Transitions>
                </Image>
            </StackPanel>
        </Button>
    </DataTemplate>
</maps:MapItemsControl.ItemTemplate>

Для получения более подробной информации, пожалуйста, обратитесь к официальному коду sample .

...