Back to Devexpress

How to: Implement a Custom Search Provider

windowsforms-117407-controls-and-libraries-map-control-examples-gis-data-searching-how-to-implement-a-custom-search-provider.md

latest7.5 KB
Original Source

How to: Implement a Custom Search Provider

  • Nov 13, 2018
  • 4 minutes to read

This example demonstrates how to create a custom search provider.

To do this, design a class inheriting the InformationDataProviderBase abstract class and implement the CreateData() method in it. Then, create a class inheriting the IInformationData interface and override its IInformationData.OnDataResponse event. Implement the Search(string keyword) method to provide custom search logic.

csharp
using DevExpress.XtraMap;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CustomSearchProvider {
    public partial class Form1 : Form {
        InformationLayer Layer { get { return (InformationLayer)mapControl1.Layers[1]; } }
        public Form1() {
            InitializeComponent();
            SearchProvider provider = new SearchProvider();
            Layer.DataProvider = provider;
        }
    }
    public class SearchProvider : InformationDataProviderBase, ISearchPanelRequestSender {
        protected new SearchData Data { get { return (SearchData)base.Data; } }
        public IEnumerable<LocationInformation> Addresses { get { return Data.Addresses; } }
        protected override IInformationData CreateData() {
            return new SearchData();
        }
        public void SearchByString(string keyword) {
            Data.Search(keyword);
        }
    }
    public class SearchData : IInformationData {
        readonly List<LocationInformation> addresses = new List<LocationInformation>();
        public IEnumerable<LocationInformation> Addresses { get { return addresses; } }
        public event EventHandler<RequestCompletedEventArgs> OnDataResponse;
        readonly TaskScheduler scheduler;
        public SearchData() {
            scheduler = TaskScheduler.FromCurrentSynchronizationContext();
        }
        RequestCompletedEventArgs CreateEventArgs() {
            MapItem[] items = new MapItem[addresses.Count];
            for (int i = 0; i < items.Length; i++)
                items[i] = new MapCallout() { Location = addresses[i].Location, Text = addresses[i].Address.FormattedAddress };
            return new RequestCompletedEventArgs(items, null, false, null);
        }
        protected void RaiseChanged() {
            if (OnDataResponse != null)
                OnDataResponse(this, CreateEventArgs());
        }
        public void Search(string keyword) {
            Task.Factory.StartNew(async () => {
                Random rnd = new Random(DateTime.Now.Millisecond);
                addresses.Clear();
                int length = keyword.Length;
                for (int i = 0; i < length; i++) {
                    LocationInformation info = new LocationInformation();
                    info.Address = new Address(keyword + " " + i.ToString());
                    info.Location = new GeoPoint(rnd.Next(180) - 90, rnd.Next(360) - 180);
                    addresses.Add(info);
                }
                await Task.Delay(500);
                RaiseChanged();
            }, CancellationToken.None, TaskCreationOptions.LongRunning | TaskCreationOptions.DenyChildAttach, scheduler);
        }
    }
    public class Address : AddressBase {
        public Address(string address) {
            this.FormattedAddress = address;
        }
    }
}
vb
Imports DevExpress.XtraMap
Imports System
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks
Imports System.Windows.Forms

Namespace CustomSearchProvider
    Partial Public Class Form1
        Inherits Form

        Private ReadOnly Property Layer() As InformationLayer
            Get
                Return CType(mapControl1.Layers(1), InformationLayer)
            End Get
        End Property
        Public Sub New()
            InitializeComponent()
            Dim provider As New SearchProvider()
            Layer.DataProvider = provider
        End Sub
    End Class
    Public Class SearchProvider
        Inherits InformationDataProviderBase
        Implements ISearchPanelRequestSender

        Protected Shadows ReadOnly Property Data() As SearchData
            Get
                Return CType(MyBase.Data, SearchData)
            End Get
        End Property

        Private ReadOnly Property Addresses As IEnumerable(Of LocationInformation) Implements ISearchPanelRequestSender.Addresses
            Get
                Return Data.Addresses
            End Get
        End Property

        Protected Overrides Function CreateData() As IInformationData
            Return New SearchData()
        End Function

        Private Sub SearchByString(keyword As String) Implements ISearchPanelRequestSender.SearchByString
            Data.Search(keyword)
        End Sub
    End Class
    Public Class SearchData
        Implements IInformationData

        Private ReadOnly addresses_Renamed As New List(Of LocationInformation)()

        Public ReadOnly Property Addresses() As IEnumerable(Of LocationInformation)
            Get
                Return addresses_Renamed
            End Get
        End Property
        Private Event OnDataResponse As EventHandler(Of RequestCompletedEventArgs) Implements IInformationData.OnDataResponse
        Private ReadOnly scheduler As TaskScheduler

        Public Sub New()
            scheduler = TaskScheduler.FromCurrentSynchronizationContext()
        End Sub
        Private Function CreateEventArgs() As RequestCompletedEventArgs
            Dim items(addresses_Renamed.Count - 1) As MapItem
            For i As Integer = 0 To items.Length - 1
                items(i) = New MapCallout() With {.Location = addresses_Renamed(i).Location, .Text = addresses_Renamed(i).Address.FormattedAddress}
            Next i
            Return New RequestCompletedEventArgs(items, Nothing, False, Nothing)
        End Function
        Protected Sub RaiseChanged()
            RaiseEvent OnDataResponse(Me, CreateEventArgs())
        End Sub
        Public Sub Search(ByVal keyword As String)
            Call Task.Factory.StartNew(Async Function()
                                           Dim rnd As Random = New Random(Date.Now.Millisecond)
                                           addresses_Renamed.Clear()
                                           Dim length = keyword.Length

                                           For i = 0 To length - 1
                                               Dim info As LocationInformation = New LocationInformation()
                                               info.Address = New Address(keyword & " " & i.ToString())
                                               info.Location = New GeoPoint(rnd.Next(180) - 90, rnd.Next(360) - 180)
                                               addresses_Renamed.Add(info)
                                           Next

                                           Await Task.Delay(500)
                                           RaiseChanged()
                                       End Function, CancellationToken.None, TaskCreationOptions.LongRunning Or TaskCreationOptions.DenyChildAttach, scheduler)
        End Sub

    End Class
    Public Class Address
        Inherits AddressBase

        Public Sub New(ByVal address As String)
            Me.FormattedAddress = address
        End Sub
    End Class
End Namespace