windowsforms-117407-controls-and-libraries-map-control-examples-gis-data-searching-how-to-implement-a-custom-search-provider.md
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.
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;
}
}
}
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