在 ViewModel 类中绑定静态类

问题描述 投票:0回答:1

我正在玩 dotnet Maui 的新地图控件。一个简单的例子是让 XAML 像:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:maps="clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.Maps"
             x:Class="SaRM.MainPage">

   <maps:Map x:Name="map" MapType="Street"/>

</ContentPage>

这样我就可以在 cs 文件后面的代码中访问“地图”:

public partial class MainPage : ContentPage
{    
    public MainPage()
    {
        InitializeComponent();  
    }

    protected override void OnAppearing()
    {
        var location = new Location(36.96, -122.0194);
        var mapSpan = new MapSpan(location, 0.01, 0.01);
        map.MoveToRegion(mapSpan);
    }
}

我想要一个 ViewModel 来与 XAML 交互,但是如果我创建一个 ViewModel 类:

public class MainViewModel
{

    public Map map;

    public MainViewModel()
    {
        var location = new Location(36.96, -122.0194);
        var mapSpan = new MapSpan(location, 0.01, 0.01);
        map.MoveToRegion(mapSpan);
    }

}

我在“地图”上遇到错误:

"Cannot declare variable of static type 'Map'"

那是因为Map是静态类。在这种情况下,我如何才能拥有一个绑定到 XAML 中的 Map 元素的 ViewModel 类?

更新: 下面是 Microsoft.Maui.Maps 中的 Map 类定义:

.net mvvm bind maui
1个回答
0
投票

UI 元素和 UI 元素类型不应在您的 ViewModel 中直接引用,正如 FreakyAli 所说。

因为

Map
是一个UI元素,所以我们不能直接在我们的ViewModel中使用它。

您可以在

YourPage.xaml
中定义Map并在您的ViewModel中添加其他必要的数据。

例如:

您可以在

Map
中添加
YourPage.xaml
并在视图模型中添加
Positions

         <maps:Map x:Name="map"
                  MapClicked="OnMapClicked"
                  ItemsSource="{Binding Positions}">
           
            <maps:Map.ItemTemplate>
                <DataTemplate>
                    <maps:Pin Location="{Binding Location}"
                              Address="{Binding Address}"
                              Label="{Binding Description}" />
                </DataTemplate>    
            </maps:Map.ItemTemplate>
        </maps:Map>

并在

map.MoveToRegion
中添加
YourPage.xaml.cs

public partial class PinItemsSourcePage : ContentPage
{
    public PinItemsSourcePage()
    {
        InitializeComponent();
        BindingContext = new PinItemsSourcePageViewModel();
        map.MoveToRegion(MapSpan.FromCenterAndRadius(new Location(39.8283459, -98.5794797), Distance.FromMiles(1500)));
    }

    void OnMapClicked(object sender, MapClickedEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine($"MapClick: {e.Location.Latitude}, {e.Location.Longitude}");
    }
}

并定义 viewModel 如下:

public class PinItemsSourcePageViewModel
{
    int _pinCreatedCount = 0;
    readonly ObservableCollection<Position> _positions;

    public IEnumerable Positions => _positions;

    public ICommand AddLocationCommand { get; }
    public ICommand RemoveLocationCommand { get; }
    public ICommand ClearLocationsCommand { get; }
    public ICommand UpdateLocationsCommand { get; }
    public ICommand ReplaceLocationCommand { get; }

    public PinItemsSourcePageViewModel()
    {
        _positions = new ObservableCollection<Position>()
        {
            new Position("New York, USA", "The City That Never Sleeps", new Location(40.67, -73.94)),
            new Position("Los Angeles, USA", "City of Angels", new Location(34.11, -118.41)),
            new Position("San Francisco, USA", "Bay City", new Location(37.77, -122.45))
        };

        AddLocationCommand = new Command(AddLocation);
        RemoveLocationCommand = new Command(RemoveLocation);
        ClearLocationsCommand = new Command(() => _positions.Clear());
        UpdateLocationsCommand = new Command(UpdateLocations);
        ReplaceLocationCommand = new Command(ReplaceLocation);
    }

    void AddLocation()
    {
        _positions.Add(NewPosition());
    }

    void RemoveLocation()
    {
        if (_positions.Any())
        {
            _positions.Remove(_positions.First());
        }
    }

    void UpdateLocations()
    {
        if (!_positions.Any())
        {
            return;
        }

        double lastLatitude = _positions.Last().Location.Latitude;
        foreach (Position position in Positions)
        {
            position.Location = new Location(lastLatitude, position.Location.Longitude);
        }
    }

    void ReplaceLocation()
    {
        if (!_positions.Any())
        {
            return;
        }

        _positions[_positions.Count - 1] = NewPosition();
    }

    Position NewPosition()
    {
        _pinCreatedCount++;
        return new Position(
            $"Pin {_pinCreatedCount}",
            $"Desc {_pinCreatedCount}",
            RandomPosition.Next(new Location(39.8283459, -98.5794797), 8, 19));
    }
}

更多信息,您可以查看文档:地图.

以上代码来自官方示例WorkingWithMaps。请注意PinItemsSourcePage.xamlPinItemsSourcePageViewModel.cs.

© www.soinside.com 2019 - 2024. All rights reserved.