Xamarin Forms Maps,通过 MVVM 单独的 CS 文件在代码中引用
Xamarin Forms Maps , referenced in code behind through MVVM seperate CS file
我正在尝试操作用 XAML 编写的 Xamarin 表单映射。
我想在单击时更改地图类型,使用命令 属性
在我的按钮对象上。我的代码隐藏在一个名为 MapViewModel 的单独的 cs 文件中。
这是我在 XAML
中的视图
<Grid.BindingContext>
<mvm:MapViewModel/>
</Grid.BindingContext>
<Grid.RowDefinitions>
<Button
HorizontalOptions="Start"
Text="Map Types"
Command="{Binding MapTypeChange}"
CommandParameter="{x:Reference Name=map}"
BackgroundColor="Olive"/>
<Button
HorizontalOptions="Center"
Text="Report NoShows"
Command="{Binding SendLocationCommand}"
CommandParameter="{x:Reference Name=MapView}"
BackgroundColor="Red"
/>
<Button
Text="Sync"
Command="{Binding SyncLocationCommand}"
CommandParameter="{x:Reference Name=MapView}"
BackgroundColor="Green"
/>
<StackLayout
Padding="5,50,5,0">
<maps:Map
Grid.Column="1"
Grid.Row="0"
WidthRequest="350"
HeightRequest="500"
x:Name="XamlMap"
IsShowingUser="true"
MapType="Hybrid" />
</StackLayout>
</Grid>
这是我的 MapViewModel
public class MapViewModel : INotifyPropertyChanged
{
private ActionCommand _sendlocationcommand;
public ActionCommand SendLocationCommand
{
get
{
if (_sendlocationcommand == null)
{
_sendlocationcommand = new ActionCommand(SendEmailLocation);
}
return _sendlocationcommand;
}
}
private ActionCommand<Page> _synclocationcommand;
public ActionCommand<Page> SyncLocationCommand
{
get
{
if (_synclocationcommand == null)
{
_synclocationcommand = new ActionCommand<Page>(SyncLocation);
}
return _synclocationcommand;
}
}
private ActionCommand<Map> _maptypecommand;
public event PropertyChangedEventHandler PropertyChanged;
public ActionCommand<Map> MapTypeCommand
{
get
{
if (_maptypecommand == null)
{
_maptypecommand = new ActionCommand<Map>(MapTypeChange);
// OnPropertyChanged("MapTypeCommand");
}
return _maptypecommand;
}
}
//**Here is where I want to manipulate the map**
private async void MapTypeChange(Map map)
{
if (map != null)
map.MapType = MapType.Satellite;
var locator = CrossGeolocator.Current;
var currentPos = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
map.MoveToRegion(MapSpan.FromCenterAndRadius(
new Xamarin.Forms.Maps.Position(currentPos.Latitude, currentPos.Longitude), Distance.FromMiles(1)));
}
private async void SyncLocation(Page page)
{
var locator = CrossGeolocator.Current;
if (locator.IsGeolocationAvailable && locator.IsGeolocationEnabled)
{
locator.DesiredAccuracy = 50;
var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
string currentposition = ($"{position.Timestamp.UtcDateTime}");
string latitude = ($"Latitude: {position.Latitude}");
string longitutde = ($" {position.Longitude}");
string latlngposition = ($"{latitude}, {longitutde}");
string cancel = "Cancel";
await page.DisplayAlert($"Synchronizing .. Please wait... :{currentposition}", $"{latlngposition}", $"{cancel}");
double lat = position.Latitude;
double lng = position.Longitude;
}
else if (!locator.IsGeolocationEnabled)
{
await page.DisplayAlert("Device Location Error :", "Is location on ? Location is off or unavaliable please check this, and restart the application", "Exit");
throw new ArgumentException("Device location not found, or unavalible,");
}
}
private async void SendEmailLocation()
{
var locator = CrossGeolocator.Current;
if (locator.IsGeolocationAvailable && locator.IsGeolocationEnabled)
{
var emailmessagebuilder = CrossMessaging.Current.EmailMessenger;
locator.DesiredAccuracy = 50;
var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
string currentposition = ($"Date & Time : {position.Timestamp.UtcDateTime}");
string latitude = ($"Latitude: {position.Latitude}");
string longitutde = ($"Longitude: {position.Longitude}");
string latlngposition = ($"Latitude :{latitude}, Longitutde :{longitutde}, {currentposition}");
if (emailmessagebuilder.CanSendEmail)
{
var email = new EmailMessageBuilder()
.To("")
.Cc("")
.Bcc(new[] { "", "" })
.Subject("")
.Body($"{latlngposition}")
.Build();
emailmessagebuilder.SendEmail(email);
}
}
else if (!locator.IsGeolocationEnabled)
{
var page = new Page();
await page.DisplayAlert("Device Location Service Error!", "Is location on ? Location is off or unavaliable please try again", "Exit");
throw new ArgumentException("Device location not found, or unavalible,");
}
}
public void OnPropertyChanged(string prop)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
}
}
我想通了。
1.Give 你的 Xaml 对象 a X:Name="XamlMap"
在Xaml文件中传递Button对象a
CommandParameter="{x:参考名称=Xaml地图}"
你的 Cs 文件处理对象的方法,你将你的对象作为参数传递给它
private void MapTypeChange(Map map)
{
var xamlMap = map.FindByName<Map>("XamlMap");
xamlMap.MapType = MapType.Satellite;
}
我们将对同一类型对象的引用传递给我们的方法。
我们使用一个变量,并使用 FindByName 传递我们的通用类型,我们
将我们的 Xaml 对象名称的字符串参数传递给我们的 FindByName。
然后我们使用变量做任何想做的事!!!
编码愉快!
我正在尝试操作用 XAML 编写的 Xamarin 表单映射。 我想在单击时更改地图类型,使用命令 属性 在我的按钮对象上。我的代码隐藏在一个名为 MapViewModel 的单独的 cs 文件中。
这是我在 XAML
中的视图<Grid.BindingContext>
<mvm:MapViewModel/>
</Grid.BindingContext>
<Grid.RowDefinitions>
<Button
HorizontalOptions="Start"
Text="Map Types"
Command="{Binding MapTypeChange}"
CommandParameter="{x:Reference Name=map}"
BackgroundColor="Olive"/>
<Button
HorizontalOptions="Center"
Text="Report NoShows"
Command="{Binding SendLocationCommand}"
CommandParameter="{x:Reference Name=MapView}"
BackgroundColor="Red"
/>
<Button
Text="Sync"
Command="{Binding SyncLocationCommand}"
CommandParameter="{x:Reference Name=MapView}"
BackgroundColor="Green"
/>
<StackLayout
Padding="5,50,5,0">
<maps:Map
Grid.Column="1"
Grid.Row="0"
WidthRequest="350"
HeightRequest="500"
x:Name="XamlMap"
IsShowingUser="true"
MapType="Hybrid" />
</StackLayout>
</Grid>
这是我的 MapViewModel
public class MapViewModel : INotifyPropertyChanged
{
private ActionCommand _sendlocationcommand;
public ActionCommand SendLocationCommand
{
get
{
if (_sendlocationcommand == null)
{
_sendlocationcommand = new ActionCommand(SendEmailLocation);
}
return _sendlocationcommand;
}
}
private ActionCommand<Page> _synclocationcommand;
public ActionCommand<Page> SyncLocationCommand
{
get
{
if (_synclocationcommand == null)
{
_synclocationcommand = new ActionCommand<Page>(SyncLocation);
}
return _synclocationcommand;
}
}
private ActionCommand<Map> _maptypecommand;
public event PropertyChangedEventHandler PropertyChanged;
public ActionCommand<Map> MapTypeCommand
{
get
{
if (_maptypecommand == null)
{
_maptypecommand = new ActionCommand<Map>(MapTypeChange);
// OnPropertyChanged("MapTypeCommand");
}
return _maptypecommand;
}
}
//**Here is where I want to manipulate the map**
private async void MapTypeChange(Map map)
{
if (map != null)
map.MapType = MapType.Satellite;
var locator = CrossGeolocator.Current;
var currentPos = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
map.MoveToRegion(MapSpan.FromCenterAndRadius(
new Xamarin.Forms.Maps.Position(currentPos.Latitude, currentPos.Longitude), Distance.FromMiles(1)));
}
private async void SyncLocation(Page page)
{
var locator = CrossGeolocator.Current;
if (locator.IsGeolocationAvailable && locator.IsGeolocationEnabled)
{
locator.DesiredAccuracy = 50;
var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
string currentposition = ($"{position.Timestamp.UtcDateTime}");
string latitude = ($"Latitude: {position.Latitude}");
string longitutde = ($" {position.Longitude}");
string latlngposition = ($"{latitude}, {longitutde}");
string cancel = "Cancel";
await page.DisplayAlert($"Synchronizing .. Please wait... :{currentposition}", $"{latlngposition}", $"{cancel}");
double lat = position.Latitude;
double lng = position.Longitude;
}
else if (!locator.IsGeolocationEnabled)
{
await page.DisplayAlert("Device Location Error :", "Is location on ? Location is off or unavaliable please check this, and restart the application", "Exit");
throw new ArgumentException("Device location not found, or unavalible,");
}
}
private async void SendEmailLocation()
{
var locator = CrossGeolocator.Current;
if (locator.IsGeolocationAvailable && locator.IsGeolocationEnabled)
{
var emailmessagebuilder = CrossMessaging.Current.EmailMessenger;
locator.DesiredAccuracy = 50;
var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
string currentposition = ($"Date & Time : {position.Timestamp.UtcDateTime}");
string latitude = ($"Latitude: {position.Latitude}");
string longitutde = ($"Longitude: {position.Longitude}");
string latlngposition = ($"Latitude :{latitude}, Longitutde :{longitutde}, {currentposition}");
if (emailmessagebuilder.CanSendEmail)
{
var email = new EmailMessageBuilder()
.To("")
.Cc("")
.Bcc(new[] { "", "" })
.Subject("")
.Body($"{latlngposition}")
.Build();
emailmessagebuilder.SendEmail(email);
}
}
else if (!locator.IsGeolocationEnabled)
{
var page = new Page();
await page.DisplayAlert("Device Location Service Error!", "Is location on ? Location is off or unavaliable please try again", "Exit");
throw new ArgumentException("Device location not found, or unavalible,");
}
}
public void OnPropertyChanged(string prop)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
}
}
我想通了。
1.Give 你的 Xaml 对象 a X:Name="XamlMap"
在Xaml文件中传递Button对象a
CommandParameter="{x:参考名称=Xaml地图}"你的 Cs 文件处理对象的方法,你将你的对象作为参数传递给它
private void MapTypeChange(Map map) { var xamlMap = map.FindByName<Map>("XamlMap"); xamlMap.MapType = MapType.Satellite; }
我们将对同一类型对象的引用传递给我们的方法。
我们使用一个变量,并使用 FindByName 传递我们的通用类型,我们
将我们的 Xaml 对象名称的字符串参数传递给我们的 FindByName。
然后我们使用变量做任何想做的事!!!
编码愉快!