C#14 field backed properties

This commit is contained in:
ClemensFischer 2025-12-27 21:24:01 +01:00
parent 5d390071c6
commit be427c195a
20 changed files with 89 additions and 106 deletions

View file

@ -18,8 +18,7 @@ namespace MapControl.MBTiles
/// </summary>
public class MBTileLayer : MapTileLayer
{
private static ILogger logger;
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger<MBTileLayer>();
private static ILogger Logger => field ??= ImageLoader.LoggerFactory?.CreateLogger<MBTileLayer>();
public static readonly DependencyProperty FileProperty =
DependencyPropertyHelper.Register<MBTileLayer, string>(nameof(File), null,

View file

@ -17,8 +17,7 @@ namespace MapControl.MBTiles
{
public sealed class MBTileSource : TileSource, IDisposable
{
private static ILogger logger;
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger<MBTileSource>();
private static ILogger Logger => field ??= ImageLoader.LoggerFactory?.CreateLogger<MBTileSource>();
private SQLiteConnection connection;

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net10.0-windows;net462</TargetFrameworks>
<LangVersion Condition="'$(TargetFramework)'=='net462'">12.0</LangVersion>
<LangVersion Condition="'$(TargetFramework)'=='net462'">14.0</LangVersion>
<UseWPF>true</UseWPF>
<DefineConstants>WPF</DefineConstants>
<RootNamespace>MapControl.MBTiles</RootNamespace>

View file

@ -24,26 +24,24 @@ namespace MapControl
public static readonly StyledProperty<double> FontSizeProperty =
TextElement.FontSizeProperty.AddOwner<MapGraticule>(new StyledPropertyMetadata<double>(12d));
private MapBase parentMap;
/// <summary>
/// Implements IMapElement.ParentMap.
/// </summary>
public MapBase ParentMap
{
get => parentMap;
get;
set
{
if (parentMap != null)
if (field != null)
{
parentMap.ViewportChanged -= OnViewportChanged;
field.ViewportChanged -= OnViewportChanged;
}
parentMap = value;
field = value;
if (parentMap != null)
if (field != null)
{
parentMap.ViewportChanged += OnViewportChanged;
field.ViewportChanged += OnViewportChanged;
}
}
}
@ -55,7 +53,7 @@ namespace MapControl
public override void Render(DrawingContext drawingContext)
{
if (parentMap != null)
if (ParentMap != null)
{
var pathGeometry = new PathGeometry();

View file

@ -62,8 +62,7 @@ namespace MapControl
private static string QueryString(ushort tag) => $"/ifd/{{ushort={tag}}}";
private static ILogger logger;
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger(typeof(GeoImage));
private static ILogger Logger => field ??= ImageLoader.LoggerFactory?.CreateLogger(typeof(GeoImage));
public static readonly DependencyProperty SourcePathProperty =
DependencyPropertyHelper.RegisterAttached<string>("SourcePath", typeof(GeoImage), null,

View file

@ -66,8 +66,7 @@ namespace MapControl
}
}
private static ILogger logger;
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger(typeof(GroundOverlay));
private static ILogger Logger => field ??= ImageLoader.LoggerFactory?.CreateLogger(typeof(GroundOverlay));
public static readonly DependencyProperty SourcePathProperty =
DependencyPropertyHelper.Register<GroundOverlay, string>(nameof(SourcePath), null,

View file

@ -17,20 +17,26 @@ namespace MapControl
{
public static partial class ImageLoader
{
private static ILogger logger;
private static ILogger Logger => logger ??= LoggerFactory?.CreateLogger(typeof(ImageLoader));
private static ILogger Logger => field ??= LoggerFactory?.CreateLogger(typeof(ImageLoader));
public static ILoggerFactory LoggerFactory { get; set; }
/// <summary>
/// The System.Net.Http.HttpClient instance used to download images.
/// </summary>
public static HttpClient HttpClient { get; set; }
static ImageLoader()
public static HttpClient HttpClient
{
HttpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(10) };
HttpClient.DefaultRequestHeaders.Add("User-Agent", $"XAML-Map-Control/{typeof(ImageLoader).Assembly.GetName().Version}");
get
{
if (field == null)
{
field = new HttpClient { Timeout = TimeSpan.FromSeconds(10) };
field.DefaultRequestHeaders.Add("User-Agent", $"XAML-Map-Control/{typeof(ImageLoader).Assembly.GetName().Version}");
}
return field;
}
set;
}
public static bool IsHttp(this Uri uri)

View file

@ -19,9 +19,6 @@ namespace MapControl
/// </summary>
public partial class MapItem : ListBoxItem, IMapElement
{
private MapBase parentMap;
private MatrixTransform mapTransform;
/// <summary>
/// Gets/sets MapPanel.AutoCollapse.
/// </summary>
@ -45,21 +42,21 @@ namespace MapControl
/// </summary>
public MapBase ParentMap
{
get => parentMap;
get;
set
{
if (parentMap != null)
if (field != null)
{
parentMap.ViewportChanged -= OnViewportChanged;
field.ViewportChanged -= OnViewportChanged;
}
parentMap = value;
field = value;
if (parentMap != null && mapTransform != null)
if (field != null && MapTransform != null)
{
// Attach ViewportChanged handler only if MapTransform is actually used.
//
parentMap.ViewportChanged += OnViewportChanged;
field.ViewportChanged += OnViewportChanged;
UpdateMapTransform();
}
@ -70,23 +67,23 @@ namespace MapControl
/// Gets a Transform for scaling and rotating geometries
/// in map coordinates (meters) to view coordinates (pixels).
/// </summary>
public Transform MapTransform
public MatrixTransform MapTransform
{
get
{
if (mapTransform == null)
if (field == null)
{
mapTransform = new MatrixTransform();
field = new MatrixTransform();
if (parentMap != null)
if (ParentMap != null)
{
parentMap.ViewportChanged += OnViewportChanged;
ParentMap.ViewportChanged += OnViewportChanged;
UpdateMapTransform();
}
}
return mapTransform;
return field;
}
}
@ -97,9 +94,9 @@ namespace MapControl
private void UpdateMapTransform()
{
if (mapTransform != null && parentMap != null && Location != null)
if (MapTransform != null && ParentMap != null && Location != null)
{
mapTransform.Matrix = parentMap.GetMapTransform(Location);
MapTransform.Matrix = ParentMap.GetMapTransform(Location);
}
}
}

View file

@ -20,8 +20,6 @@ namespace MapControl
DependencyPropertyHelper.Register<MapPath, Location>(nameof(Location), null,
(path, oldValue, newValue) => path.UpdateData());
private MapBase parentMap;
/// <summary>
/// Gets or sets a Location that is used as
/// - either the origin point of a geometry specified in projected map coordinates (meters)
@ -40,19 +38,19 @@ namespace MapControl
/// </summary>
public MapBase ParentMap
{
get => parentMap;
get;
set
{
if (parentMap != null)
if (field != null)
{
parentMap.ViewportChanged -= OnViewportChanged;
field.ViewportChanged -= OnViewportChanged;
}
parentMap = value;
field = value;
if (parentMap != null)
if (field != null)
{
parentMap.ViewportChanged += OnViewportChanged;
field.ViewportChanged += OnViewportChanged;
}
UpdateData();
@ -66,9 +64,9 @@ namespace MapControl
protected virtual void UpdateData()
{
if (parentMap != null && Location != null && Data != null)
if (ParentMap != null && Location != null && Data != null)
{
SetDataTransform(parentMap.GetMapTransform(Location));
SetDataTransform(ParentMap.GetMapTransform(Location));
}
MapPanel.SetLocation(this, Location);
@ -78,13 +76,13 @@ namespace MapControl
{
var longitudeOffset = 0d;
if (parentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical && location != null)
if (ParentMap.MapProjection.Type <= MapProjectionType.NormalCylindrical && location != null)
{
var position = parentMap.LocationToView(location);
var position = ParentMap.LocationToView(location);
if (position.HasValue && !parentMap.InsideViewBounds(position.Value))
if (position.HasValue && !ParentMap.InsideViewBounds(position.Value))
{
longitudeOffset = parentMap.CoerceLongitude(location.Longitude) - location.Longitude;
longitudeOffset = ParentMap.CoerceLongitude(location.Longitude) - location.Longitude;
}
}
@ -93,7 +91,7 @@ namespace MapControl
protected Point? LocationToMap(Location location, double longitudeOffset)
{
var point = parentMap.MapProjection.LocationToMap(location.Latitude, location.Longitude + longitudeOffset);
var point = ParentMap.MapProjection.LocationToMap(location.Latitude, location.Longitude + longitudeOffset);
if (point.HasValue)
{
@ -116,7 +114,7 @@ namespace MapControl
if (point.HasValue)
{
point = parentMap.ViewTransform.MapToViewMatrix.Transform(point.Value);
point = ParentMap.ViewTransform.MapToViewMatrix.Transform(point.Value);
}
return point;

View file

@ -31,12 +31,10 @@ namespace MapControl
public const double Wgs84Flattening = 1d / 298.257223563;
public static readonly double Wgs84Eccentricity = Math.Sqrt((2d - Wgs84Flattening) * Wgs84Flattening);
private static MapProjectionFactory factory;
public static MapProjectionFactory Factory
{
get => factory ??= new MapProjectionFactory();
set => factory = value;
get => field ??= new MapProjectionFactory();
set;
}
/// <summary>

View file

@ -29,8 +29,7 @@ namespace MapControl
public class TileImageLoader : ITileImageLoader
{
private static ILogger logger;
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger(typeof(TileImageLoader));
private static ILogger Logger => field ??= ImageLoader.LoggerFactory?.CreateLogger(typeof(TileImageLoader));
/// <summary>
/// Default folder path where a persistent cache implementation may save data, i.e. "C:\ProgramData\MapControl\TileCache".

View file

@ -52,8 +52,6 @@ namespace MapControl
private readonly Progress<double> loadingProgress;
private readonly UpdateTimer updateTimer;
private ITileImageLoader tileImageLoader;
private MapBase parentMap;
protected TilePyramidLayer()
{
@ -73,8 +71,8 @@ namespace MapControl
public ITileImageLoader TileImageLoader
{
get => tileImageLoader ??= new TileImageLoader();
set => tileImageLoader = value;
get => field ??= new TileImageLoader();
set;
}
/// <summary>
@ -152,26 +150,26 @@ namespace MapControl
/// </summary>
public MapBase ParentMap
{
get => parentMap;
get;
set
{
if (parentMap != null)
if (field != null)
{
parentMap.ViewportChanged -= OnViewportChanged;
field.ViewportChanged -= OnViewportChanged;
}
parentMap = value;
field = value;
if (parentMap != null)
if (field != null)
{
parentMap.ViewportChanged += OnViewportChanged;
field.ViewportChanged += OnViewportChanged;
}
updateTimer.Run();
}
}
public bool IsBaseMapLayer => parentMap != null && parentMap.Children.Count > 0 && parentMap.Children[0] == this;
public bool IsBaseMapLayer => ParentMap != null && ParentMap.Children.Count > 0 && ParentMap.Children[0] == this;
public abstract IReadOnlyCollection<string> SupportedCrsIds { get; }

View file

@ -4,22 +4,21 @@ namespace MapControl
{
public class UriTileSource : TileSource
{
private string uriTemplate;
private string uriFormat;
public string UriTemplate
{
get => uriTemplate;
get;
set
{
uriTemplate = value;
uriFormat = uriTemplate
field = value;
uriFormat = field
.Replace("{z}", "{0}")
.Replace("{x}", "{1}")
.Replace("{y}", "{2}")
.Replace("{s}", "{3}");
if (Subdomains == null && uriTemplate.Contains("{s}"))
if (Subdomains == null && field.Contains("{s}"))
{
Subdomains = ["a", "b", "c"]; // default OpenStreetMap subdomains
}

View file

@ -27,8 +27,7 @@ namespace MapControl
/// </summary>
public class WmsImageLayer : MapImageLayer
{
private static ILogger logger;
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger(typeof(WmsImageLayer));
private static ILogger Logger => field ??= ImageLoader.LoggerFactory?.CreateLogger(typeof(WmsImageLayer));
public static readonly DependencyProperty ServiceUriProperty =
DependencyPropertyHelper.Register<WmsImageLayer, Uri>(nameof(ServiceUri), null,

View file

@ -28,8 +28,7 @@ namespace MapControl
/// </summary>
public class WmtsTileLayer : TilePyramidLayer
{
private static ILogger logger;
private static ILogger Logger => logger ??= ImageLoader.LoggerFactory?.CreateLogger(typeof(WmtsTileLayer));
private static ILogger Logger => field ??= ImageLoader.LoggerFactory?.CreateLogger(typeof(WmtsTileLayer));
public static readonly DependencyProperty CapabilitiesUriProperty =
DependencyPropertyHelper.Register<WmtsTileLayer, Uri>(nameof(CapabilitiesUri));

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net10.0-windows;net462</TargetFrameworks>
<LangVersion Condition="'$(TargetFramework)'=='net462'">12.0</LangVersion>
<LangVersion Condition="'$(TargetFramework)'=='net462'">14.0</LangVersion>
<UseWPF>true</UseWPF>
<DefineConstants>WPF</DefineConstants>
<RootNamespace>MapControl</RootNamespace>

View file

@ -18,26 +18,24 @@ namespace MapControl
public static readonly DependencyProperty FontSizeProperty =
TextElement.FontSizeProperty.AddOwner(typeof(MapGraticule), new FrameworkPropertyMetadata(12d));
private MapBase parentMap;
/// <summary>
/// Implements IMapElement.ParentMap.
/// </summary>
public MapBase ParentMap
{
get => parentMap;
get;
set
{
if (parentMap != null)
if (field != null)
{
parentMap.ViewportChanged -= OnViewportChanged;
field.ViewportChanged -= OnViewportChanged;
}
parentMap = value;
field = value;
if (parentMap != null)
if (field != null)
{
parentMap.ViewportChanged += OnViewportChanged;
field.ViewportChanged += OnViewportChanged;
}
}
}
@ -49,7 +47,7 @@ namespace MapControl
protected override void OnRender(DrawingContext drawingContext)
{
if (parentMap != null)
if (ParentMap != null)
{
var pathGeometry = new PathGeometry();

View file

@ -17,8 +17,6 @@ namespace MapControl.Projections
/// </summary>
public class GeoApiProjection : MapProjection
{
private IProjectedCoordinateSystem coordinateSystem;
protected GeoApiProjection()
{
}
@ -44,23 +42,23 @@ namespace MapControl.Projections
/// </summary>
public IProjectedCoordinateSystem CoordinateSystem
{
get => coordinateSystem;
get;
protected set
{
coordinateSystem = value ?? throw new ArgumentNullException(nameof(value));
field = value ?? throw new ArgumentNullException(nameof(value));
var transformFactory = new CoordinateTransformationFactory();
LocationToMapTransform = transformFactory
.CreateFromCoordinateSystems(GeographicCoordinateSystem.WGS84, coordinateSystem)
.CreateFromCoordinateSystems(GeographicCoordinateSystem.WGS84, field)
.MathTransform;
MapToLocationTransform = transformFactory
.CreateFromCoordinateSystems(coordinateSystem, GeographicCoordinateSystem.WGS84)
.CreateFromCoordinateSystems(field, GeographicCoordinateSystem.WGS84)
.MathTransform;
CrsId = !string.IsNullOrEmpty(coordinateSystem.Authority) && coordinateSystem.AuthorityCode > 0
? $"{coordinateSystem.Authority}:{coordinateSystem.AuthorityCode}"
CrsId = !string.IsNullOrEmpty(field.Authority) && field.AuthorityCode > 0
? $"{field.Authority}:{field.AuthorityCode}"
: string.Empty;
if (CrsId == "EPSG:3857")
@ -69,7 +67,7 @@ namespace MapControl.Projections
}
else
{
var projection = coordinateSystem.Projection ??
var projection = field.Projection ??
throw new ArgumentException("CoordinateSystem.Projection must not be null.", nameof(value));
var centralMeridian = projection.GetParameter("central_meridian") ?? projection.GetParameter("longitude_of_origin");
@ -98,7 +96,7 @@ namespace MapControl.Projections
public override Point GetRelativeScale(double latitude, double longitude)
{
var k = coordinateSystem?.Projection?.GetParameter("scale_factor")?.Value ?? 1d;
var k = CoordinateSystem?.Projection?.GetParameter("scale_factor")?.Value ?? 1d;
return new Point(k, k);
}

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net10.0-windows;net462</TargetFrameworks>
<LangVersion Condition="'$(TargetFramework)'=='net462'">12.0</LangVersion>
<LangVersion Condition="'$(TargetFramework)'=='net462'">14.0</LangVersion>
<UseWPF>true</UseWPF>
<DefineConstants>WPF</DefineConstants>
<RootNamespace>MapControl.Projections</RootNamespace>

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net10.0-windows;net462</TargetFrameworks>
<LangVersion Condition="'$(TargetFramework)'=='net462'">12.0</LangVersion>
<LangVersion Condition="'$(TargetFramework)'=='net462'">14.0</LangVersion>
<UseWPF>true</UseWPF>
<DefineConstants>WPF</DefineConstants>
<RootNamespace>MapControl.UiTools</RootNamespace>