Skip to main content

LayerBase.ViewportChanged Event

Occurs every time the current viewport is changed.

Namespace: DevExpress.Xpf.Map

Assembly: DevExpress.Xpf.Map.v23.2.dll

NuGet Package: DevExpress.Wpf.Map

Declaration

public event ViewportChangedEventHandler ViewportChanged

Event Data

The ViewportChanged event's data class is ViewportChangedEventArgs. The following properties provide information specific to this event:

Property Description
Angle Returns the Map Control’s rotation angle in degrees.
BottomRight Returns the bottom-right coordinate of the current viewport.
IsAnimated
TopLeft Returns the top-left coordinate of the current viewport.
ZoomLevel Returns the zoom level of the current viewport.

Remarks

How to Detect Visible Items

The following example shows how to determine the number of visible vector items (in this example, map dots) on the map surface. A list box contains the coordinates of the visible items and a text label displays their number. The list of visible items is re-calculated when the map viewport is changed. For example, when a user zooms the map.

A map with a list of visible dots

To do so, handle the ViewportChanged event of the layer that contains vector items. In the event handler, determine whether item coordinates are in the viewport. The viewport boundaries are defined by the e.TopLeft and e.BottomRight properties:

<dx:ThemedWindow xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
    xmlns:dxm="http://schemas.devexpress.com/winfx/2008/xaml/map" 
    x:Class="DetectVisibleItems.MainWindow"
    Title="MainWindow" Height="800" Width="1000">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="3*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="7*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>

        <dxm:MapControl x:Name="mapControl1" Grid.Column="0" Grid.RowSpan="2">
            <dxm:VectorLayer ViewportChanged="VectorLayer_ViewportChanged">
                <dxm:MapItemStorage/>
            </dxm:VectorLayer>
        </dxm:MapControl>
        <dxe:ListBoxEdit x:Name="listBox" Grid.Column="1" SelectedIndexChanged="listBox_SelectedIndexChanged"/>
        <dxe:TextEdit x:Name="textEdit" Grid.Column="1" Grid.Row="1"/>
    </Grid>
</dx:ThemedWindow>
using DevExpress.Map;
using DevExpress.Xpf.Core;
using DevExpress.Xpf.Map;
using System.Collections.Generic;
using System.Linq;

namespace DetectVisibleItems {
    public partial class MainWindow : ThemedWindow {
        VectorLayer Layer { get { return (VectorLayer)mapControl1.Layers[0]; } }
        MapItemStorage Data { get { return (MapItemStorage)Layer.Data; } }
        public MainWindow() {
            InitializeComponent();
            Data.Items.AddRange(CreateItems());
            UpdateVisibleItemsList(new GeoPoint(90, -180), new GeoPoint(-90, 180));
        }
        static bool IsPointInside(CoordPoint point, CoordPoint topLeft, CoordPoint bottomRight) {
            return (point.GetY() >= bottomRight.GetY()) && (point.GetY() <= topLeft.GetY()) &&
                   (point.GetX() >= topLeft.GetX()) && (point.GetX() <= bottomRight.GetX());
        }
        static List<MapDot> CreateItems() {
            List<MapDot> result = new List<MapDot>();
            for (double lat = -80; lat <= 80; lat += 20)
                for (double lon = -180; lon <= 180; lon += 20)
                    result.Add(new MapDot() { Location = new GeoPoint(lat, lon), Size = 15 });
            return result;
        }
        void UpdateVisibleItemsList(CoordPoint topLeft, CoordPoint bottomRight) {
            IEnumerable<CoordPoint> visibleItems = Data.Items.Select(item => ((MapDot)item).Location).
                                                              Where(location => IsPointInside(location, topLeft, bottomRight));
            listBox.Items.Clear();
            listBox.Items.AddRange(visibleItems.ToArray());
            textEdit.Text = $"Item Count: {listBox.Items.Count}";
        }

        private void VectorLayer_ViewportChanged(object sender, ViewportChangedEventArgs e) {
            if (!e.IsAnimated)
                UpdateVisibleItemsList(e.TopLeft, e.BottomRight);        }

        private void listBox_SelectedIndexChanged(object sender, System.Windows.RoutedEventArgs e) {
            if (Layer.SelectedItems.Count != 0) Layer.SelectedItems.Clear();
            if (listBox.SelectedIndex >= 0) {
                Layer.SelectedItems.Add(Data.Items[listBox.SelectedIndex]);
            }
        }
    }
}
See Also