Skip to content

Commit 709176b

Browse files
Bugfix: Fixing bug with EnableDefaultWorldGeocode value not being honored in MAUI (#655)
* Add Loaded event handler to SearchView for initialization * Refactor SearchView event handling logic Removed the unsubscribe line from `SearchView_Loaded`. Added a check in `HandleViewpointChanged` to ensure the view is loaded before executing logic. * Update default value for EnableDefaultWorldGeocoder * Adding extra safety check for Laoded and unlaoded event * Refactor loading tasks and lifecycle management - Changed `_loadTask` in `LocatorSearchSource` to `Lazy<Task>` for lazy initialization. - Modified `WorldGeocoderSearchSource` to use `Lazy<Task>` for `_additionalLoadTask`. * - Enhanced LocatorSearchSource and simplify loading tasks - Updated LocatorSearchSource to implement INotifyPropertyChanged, introducing a new display name management system. - - Removed the _additionalLoadTask from WorldGeocoderSearchSource, simplifying the loading process to rely only on LoadTask. * Adjusting Spacing * - Introduced `OnPropertyChanged` method. - Modified logic to ensure `_displayName` is set to an empty string if both `Name` and `Description` are unavailable, preventing potential null states. - Added `ProeprtyChanged` Event for DisplayName When Refresh happens. * Added a new entry in `Resources.resx` for the default display name "Locator".
1 parent 05cd1a6 commit 709176b

File tree

7 files changed

+82
-49
lines changed

7 files changed

+82
-49
lines changed

src/Toolkit/Toolkit.Maui/SearchView/SearchView.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public partial class SearchView : TemplatedView, INotifyPropertyChanged
4848

4949
private bool _sourceSelectToggled;
5050

51+
private bool _loadedHandled;
52+
5153
/// <summary>
5254
/// Initializes a new instance of the <see cref="SearchView"/> class.
5355
/// </summary>
@@ -81,6 +83,16 @@ public SearchView()
8183
ClearCommand = new DelegateCommand(HandleClearSearchCommand);
8284
SearchCommand = new DelegateCommand(HandleSearchCommand);
8385
RepeatSearchHereCommand = new DelegateCommand(HandleRepeatSearchHereCommand);
86+
Loaded += SearchView_Loaded;
87+
}
88+
89+
private void SearchView_Loaded(object? sender, EventArgs e)
90+
{
91+
if (GeoView != null)
92+
{
93+
HandleViewpointChanged();
94+
}
95+
_ = ConfigureForCurrentConfiguration();
8496
}
8597

8698
private void InitializeLocalizedStrings()
@@ -450,8 +462,6 @@ private static void OnGeoViewPropertyChanged(BindableObject sender, object? oldV
450462
newGeoView.ViewpointChanged += sendingView.GeoView_ViewpointChanged;
451463
newGeoView.GraphicsOverlays?.Add(sendingView._resultOverlay);
452464
}
453-
454-
_ = sendingView.ConfigureForCurrentConfiguration();
455465
}
456466
}
457467

@@ -531,7 +541,6 @@ private void HandleMapChange(object? sender, PropertyChangedEventArgs e)
531541
{
532542
if (e.PropertyName == nameof(Mapping.Map) || e.PropertyName == nameof(Scene))
533543
{
534-
_ = ConfigureForCurrentConfiguration();
535544
return;
536545
}
537546

@@ -545,8 +554,6 @@ private void HandleMapChange(object? sender, PropertyChangedEventArgs e)
545554
{
546555
_lastUsedGeomodel = scene;
547556
}
548-
549-
_ = ConfigureForCurrentConfiguration();
550557
}
551558
}
552559

@@ -620,7 +627,7 @@ private void SearchViewModel_PropertyChanged(object? sender, PropertyChangedEven
620627
/// </summary>
621628
private void HandleViewpointChanged()
622629
{
623-
if (SearchViewModel == null)
630+
if (!IsLoaded || SearchViewModel == null)
624631
{
625632
return;
626633
}

src/Toolkit/Toolkit.UI.Controls/SearchView/SearchView.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ public string? RepeatSearchButtonText
615615
/// Identifies the <see cref="EnableDefaultWorldGeocoder"/> dependency property.
616616
/// </summary>
617617
public static readonly DependencyProperty EnableDefaultWorldGeocoderProperty =
618-
DependencyProperty.Register(nameof(EnableDefaultWorldGeocoder), typeof(bool), typeof(SearchView), new PropertyMetadata(false, OnEnableDefualtWorldGeocoderPropertyChanged));
618+
DependencyProperty.Register(nameof(EnableDefaultWorldGeocoder), typeof(bool), typeof(SearchView), new PropertyMetadata(true, OnEnableDefualtWorldGeocoderPropertyChanged));
619619

620620
/// <summary>
621621
/// Identifies the <see cref="EnableRepeatSearchHereButton"/> dependency proeprty.

src/Toolkit/Toolkit.WPF/UI/Controls/SearchView/SearchView.Theme.xaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,5 @@
569569
<Setter Property="VerticalAlignment" Value="Top" />
570570
<Setter Property="Width" Value="256" />
571571
<Setter Property="Margin" Value="4" />
572-
<Setter Property="EnableDefaultWorldGeocoder" Value="True" />
573572
</Style>
574573
</ResourceDictionary>

src/Toolkit/Toolkit.WinUI/UI/Controls/SearchView/SearchView.Theme.xaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,5 @@
653653
<Setter Property="VerticalAlignment" Value="Top" />
654654
<Setter Property="Width" Value="256" />
655655
<Setter Property="Margin" Value="4" />
656-
<Setter Property="EnableDefaultWorldGeocoder" Value="True" />
657656
</Style>
658657
</ResourceDictionary>

src/Toolkit/Toolkit/LocalizedStrings/Resources.resx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,4 +533,8 @@
533533
<value>Zoom to result</value>
534534
<comment>The text on button that zooms to the selected trace result.</comment>
535535
</data>
536+
<data name="Locator_DefaultName" xml:space="preserve">
537+
<value>Locator</value>
538+
<comment>Default display name for LocatorSearchSource if locator name is not set.</comment>
539+
</data>
536540
</root>

src/Toolkit/Toolkit/UI/Controls/SearchView/LocatorSearchSource.cs

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
using System;
1818
using System.Collections.Generic;
19+
using System.ComponentModel;
1920
using System.IO;
2021
using System.Linq;
2122
using System.Reflection;
@@ -36,7 +37,7 @@ namespace Esri.ArcGISRuntime.Toolkit.UI.Controls
3637
/// <summary>
3738
/// Basic search source implementation for generic locators.
3839
/// </summary>
39-
public class LocatorSearchSource : ISearchSource
40+
public class LocatorSearchSource : ISearchSource, INotifyPropertyChanged
4041
{
4142
internal const string WorldGeocoderUriString = "https://geocode-api.arcgis.com/arcgis/rest/services/World/GeocodeServer";
4243

@@ -62,17 +63,41 @@ public static async Task<LocatorSearchSource> CreateDefaultSourceAsync(Cancellat
6263
return new WorldGeocoderSearchSource(_worldGeocoderTask, null);
6364
}
6465

65-
private readonly Task _loadTask;
6666

67+
/// <inheritdoc/>
68+
public event PropertyChangedEventHandler? PropertyChanged;
69+
70+
/// <summary>
71+
/// Raises the <see cref="PropertyChanged"/> event for the specified property.
72+
/// </summary>
73+
/// <param name="propertyName">The name of the property that changed.</param>
74+
protected virtual void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
75+
76+
private readonly Lazy<Task> _loadTask;
6777
/// <summary>
6878
/// Gets the task used to perform initial locator setup.
6979
/// </summary>
70-
protected Task LoadTask => _loadTask;
80+
protected Lazy<Task> LoadTask => _loadTask;
81+
82+
private string _displayName = string.Empty;
83+
private bool _displayNameSetExternally = false;
7184

7285
/// <summary>
7386
/// Gets or sets the name of the locator. Defaults to the locator's name, or "locator" if not set.
7487
/// </summary>
75-
public string DisplayName { get; set; } = "Locator";
88+
public string DisplayName
89+
{
90+
get => _displayName;
91+
set
92+
{
93+
if (_displayName != value)
94+
{
95+
_displayName = value;
96+
_displayNameSetExternally = true;
97+
OnPropertyChanged(nameof(DisplayName));
98+
}
99+
}
100+
}
76101

77102
/// <summary>
78103
/// Gets or sets the maximum number of results to return for a search. Default is 6.
@@ -146,12 +171,36 @@ public LocatorSearchSource(LocatorTask locator)
146171
{
147172
Locator = locator;
148173

149-
_loadTask = EnsureLoaded();
174+
RefreshDisplayName();
175+
176+
_loadTask = new Lazy<Task>(EnsureLoaded);
177+
}
178+
179+
private void RefreshDisplayName()
180+
{
181+
if (_displayNameSetExternally)
182+
return;
183+
184+
if (Locator?.LocatorInfo is LocatorInfo info)
185+
{
186+
// Locators from online services have descriptions but not names.
187+
if (!string.IsNullOrWhiteSpace(info.Name) && info.Name != Locator.Uri?.ToString())
188+
_displayName = info.Name;
189+
else if (!string.IsNullOrWhiteSpace(info.Description))
190+
_displayName = info.Description;
191+
else
192+
_displayName = Properties.Resources.GetString("Locator_DefaultName") ?? string.Empty;
193+
194+
OnPropertyChanged(nameof(DisplayName));
195+
}
196+
197+
GeocodeParameters.ResultAttributeNames.Add("*");
150198
}
151199

152200
private async Task EnsureLoaded()
153201
{
154202
await Locator.LoadAsync();
203+
RefreshDisplayName();
155204
#if MAUI
156205
Stream? resourceStream = Assembly.GetAssembly(typeof(LocatorSearchSource))?.GetManifestResourceStream(
157206
"Esri.ArcGISRuntime.Toolkit.Maui.Assets.pin-red.png");
@@ -169,13 +218,6 @@ private async Task EnsureLoaded()
169218
pinSymbol.OffsetY = 16.5;
170219
DefaultSymbol = pinSymbol;
171220
}
172-
173-
if (DisplayName != Locator?.LocatorInfo?.Name && !string.IsNullOrWhiteSpace(Locator?.LocatorInfo?.Name))
174-
{
175-
DisplayName = Locator?.LocatorInfo?.Name ?? "Locator";
176-
}
177-
178-
GeocodeParameters.ResultAttributeNames.Add("*");
179221
}
180222

181223
/// <summary>
@@ -197,7 +239,7 @@ public virtual void NotifyDeselected(SearchResult? result)
197239
/// <inheritdoc/>
198240
public virtual async Task<IList<SearchSuggestion>> SuggestAsync(string queryString, CancellationToken cancellationToken = default)
199241
{
200-
await _loadTask;
242+
await LoadTask.Value;
201243

202244
cancellationToken.ThrowIfCancellationRequested();
203245

@@ -214,7 +256,7 @@ public virtual async Task<IList<SearchSuggestion>> SuggestAsync(string queryStri
214256
/// <inheritdoc/>
215257
public virtual async Task<IList<SearchResult>> SearchAsync(SearchSuggestion suggestion, CancellationToken cancellationToken = default)
216258
{
217-
await _loadTask;
259+
await LoadTask.Value;
218260

219261
cancellationToken.ThrowIfCancellationRequested();
220262

@@ -228,7 +270,7 @@ public virtual async Task<IList<SearchResult>> SearchAsync(SearchSuggestion sugg
228270
/// <inheritdoc/>
229271
public virtual async Task<IList<SearchResult>> SearchAsync(string queryString, CancellationToken cancellationToken = default)
230272
{
231-
await _loadTask;
273+
await LoadTask.Value;
232274

233275
cancellationToken.ThrowIfCancellationRequested();
234276

@@ -246,7 +288,7 @@ public virtual async Task<IList<SearchResult>> SearchAsync(string queryString, C
246288
/// <inheritdoc />
247289
public virtual async Task<IList<SearchResult>> RepeatSearchAsync(string queryString, Envelope queryExtent, CancellationToken cancellationToken = default)
248290
{
249-
await _loadTask;
291+
await LoadTask.Value;
250292

251293
cancellationToken.ThrowIfCancellationRequested();
252294

src/Toolkit/Toolkit/UI/Controls/SearchView/WorldGeocoderSearchSource.cs

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ internal class WorldGeocoderSearchSource : LocatorSearchSource
3939
// Attribute used to identify the type of result coming from the locaotr.
4040
private const string LocatorIconAttributeKey = "Type";
4141

42-
private readonly Task _additionalLoadTask;
43-
4442
/// <summary>
4543
/// Gets or sets the minimum number of results to attempt to return.
4644
/// If there are too few results, the search is repeated with loosened parameters until enough results are accumulated.
@@ -87,27 +85,11 @@ public WorldGeocoderSearchSource(LocatorTask locator, SymbolStyle? style)
8785
{
8886
ResultSymbolStyle = style;
8987
}
90-
91-
_additionalLoadTask = EnsureLoaded();
88+
InitializeLocatorAttributes();
9289
}
9390

94-
private async Task EnsureLoaded()
91+
private void InitializeLocatorAttributes()
9592
{
96-
await LoadTask;
97-
98-
if (Locator.LocatorInfo is LocatorInfo info)
99-
{
100-
// Locators from online services have descriptions but not names.
101-
if (!string.IsNullOrWhiteSpace(info.Name) && info.Name != Locator.Uri?.ToString())
102-
{
103-
DisplayName = info.Name;
104-
}
105-
else if (!string.IsNullOrWhiteSpace(info.Description))
106-
{
107-
DisplayName = info.Description;
108-
}
109-
}
110-
11193
// Add attributes expected from the World Geocoder Service if present, otherwise default to all attributes.
11294
if (Locator.Uri?.ToString() == WorldGeocoderUriString &&
11395
(Locator.LocatorInfo?.ResultAttributes?.Any() == true))
@@ -140,7 +122,7 @@ private IList<SearchSuggestion> SuggestionToSearchSuggestion(IReadOnlyList<Sugge
140122
/// <inheritdoc />
141123
public override async Task<IList<SearchResult>> SearchAsync(SearchSuggestion suggestion, CancellationToken cancellationToken = default)
142124
{
143-
await _additionalLoadTask;
125+
await LoadTask.Value;
144126
cancellationToken.ThrowIfCancellationRequested();
145127

146128
var tempParams = new GeocodeParameters();
@@ -167,7 +149,7 @@ private SearchSuggestion SuggestResultToSearchSuggestion(SuggestResult r)
167149
/// <inheritdoc/>
168150
public override async Task<IList<SearchSuggestion>> SuggestAsync(string queryString, CancellationToken cancellationToken = default)
169151
{
170-
await _additionalLoadTask;
152+
await LoadTask.Value;
171153
cancellationToken.ThrowIfCancellationRequested();
172154

173155
SuggestParameters.PreferredSearchLocation = PreferredSearchLocation;
@@ -197,7 +179,7 @@ public override async Task<IList<SearchSuggestion>> SuggestAsync(string queryStr
197179
/// <inheritdoc/>
198180
public override async Task<IList<SearchResult>> SearchAsync(string queryString, CancellationToken cancellationToken = default)
199181
{
200-
await _additionalLoadTask;
182+
await LoadTask.Value;
201183
cancellationToken.ThrowIfCancellationRequested();
202184

203185
// Reset spatial parameters
@@ -230,7 +212,7 @@ public override async Task<IList<SearchResult>> SearchAsync(string queryString,
230212
/// </summary>
231213
public override async Task<IList<SearchResult>> RepeatSearchAsync(string queryString, Geometry.Envelope queryArea, CancellationToken cancellationToken = default)
232214
{
233-
await _additionalLoadTask;
215+
await LoadTask.Value;
234216
cancellationToken.ThrowIfCancellationRequested();
235217

236218
// Reset spatial parameters

0 commit comments

Comments
 (0)