Xamarin Forms Maps,通过MVVM单独的CS文件在代码中引用

时间:2017-03-10 19:35:38

标签: c# mvvm xamarin.forms

我正在尝试操作用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 个答案:

答案 0 :(得分:0)

我明白了。

1.给你的Xaml对象一个X:Name =“XamlMap”

  1. 在Xaml文件中传递Button对象a CommandParameter =“{x:参考名称= XamlMap}”

  2. 您的Cs文件处理对象的方法,您将对象作为参数传递给它

    private  void MapTypeChange(Map map)
    {
    
        var xamlMap = map.FindByName<Map>("XamlMap");
        xamlMap.MapType = MapType.Satellite;
    
    }
    
  3. 我们将方法传递给相同类型的对象。

    我们使用一个变量,并使用FindByName传递我们的泛型类型,我们

    将我们的FindByName传递给我们的Xaml对象名称的字符串参数。

    然后我们使用变量来做任何想要的事情!

    快乐的编码!