У меня есть карта форм Xamarin, которая показывает коллекцию Пинов. Когда я добавляю новое местоположение, он не показывает вновь созданный контакт, пока я не нажму 'Refre sh'.
У меня изначально была подписка AddLocation в конструкторе ViewModel, и она работала, но добавила закрепите 3 раза в базе данных и карту. После перемещения подписки AddLocation и отмены подписки на их собственные методы в ViewModel и вызова затем OnAppearing () и OnDisappearing () новый вывод не отображается.
Карта находится на странице с именем ItemPage.xaml
<ContentPage.ToolbarItems>
<ToolbarItem Text="Add" Clicked="ToolbarItem_Clicked" />
<ToolbarItem Text="Refresh" Clicked="ToolbarItem_Clicked_1" />
</ContentPage.ToolbarItems>
<ContentPage.Content>
<!--The map-->
<ContentView Content="{Binding Map}" />
</ContentPage.Content>
и код позади -
[DesignTimeVisible(false)]
public partial class ItemPage : ContentPage
{
ItemViewModel viewModel;
public ItemPage()
{
InitializeComponent();
BindingContext = viewModel = new ItemViewModel();
}
private void Button_Clicked(object sender, EventArgs e)
{
}
protected override void OnAppearing()
{
base.OnAppearing();
}
async void ToolbarItem_Clicked(object sender, EventArgs e)
{
await Navigation.PushModalAsync(new NavigationPage(new NewLocationPage()));
}
private void ToolbarItem_Clicked_1(object sender, EventArgs e)
{
viewModel.LoadLocationsCommand.Execute(null);
}
}
Модель представления -
public class ItemViewModel : BaseViewModel
{
public ObservableCollection<MapPinModel> Locations { get; set; }
public ObservableCollection<ItemModel> Items { get; set; }
public Command LoadLocationsCommand { get; set; }
public Command LoadItemsCommand { get; set; }
public Map Map { get; private set; }
public ItemViewModel()
{
Title = "Items";
Locations = new ObservableCollection<MapPinModel>();
Items = new ObservableCollection<ItemModel>();
LoadLocationsCommand = new Command(async () => await ExecuteLoadLocationsCommand());
LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());
Map = new Map(MapSpan.FromCenterAndRadius(
new Xamarin.Forms.Maps.Position(53.70251232638285, -1.8018436431884768),
Distance.FromMiles(0.5)))
{
IsShowingUser = true,
VerticalOptions = LayoutOptions.FillAndExpand
};
this.LoadLocationsCommand.Execute(null);
}
public void UnsubscribeMessages()
{
MessagingCenter.Unsubscribe<NewLocationPage, ItemLocationModel>(this, "AddLocation");
}
public void SubscribeMessages()
{
MessagingCenter.Subscribe<NewLocationPage, ItemLocationModel>(this, "AddLocation", async (obj, item) =>
{
await ItemDataStore.AddItemLocationAsync(item);
});
}
async Task ExecuteLoadItemsCommand()
{
if (IsBusy)
return;
try
{
Items.Clear();
var items = await ItemDataStore.GetItemsAsync(true);
foreach (var item in items)
{
Items.Add(item);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
IsBusy = false;
}
}
async Task ExecuteLoadLocationsCommand()
{
Map.Pins.Clear();
var locations = await ItemDataStore.GetLocationsAsync(true);
foreach (Feature feature in locations.Features)
{
if (!feature.Geometry.Type.Equals(GeoJSONObjectType.Point))
continue;
Point point = feature.Geometry as Point;
GeoJSON.Net.Geometry.Position s = point.Coordinates as GeoJSON.Net.Geometry.Position;
MapPinModel pin = new MapPinModel
{
PopupContent = feature.Properties["popupContent"].ToString(),
ScientificName = feature.Properties["scientificname"].ToString(),
ItemDescription = feature.Properties["description"].ToString(),
AddedBy = feature.Properties["username"].ToString(),
Latitude = s.Latitude.ToString(),
Longitude = s.Longitude.ToString()
};
Xamarin.Forms.Maps.Position position = new Xamarin.Forms.Maps.Position(Convert.ToDouble(pin.Latitude), Convert.ToDouble(pin.Longitude));
Pin newPin = new Pin
{
Label = pin.PopupContent,
Type = PinType.Place,
Position = position
};
Map.Pins.Add(newPin);
}
}
}
Наконец, страница нового местоположения -
[DesignTimeVisible(false)]
public partial class NewLocationPage : ContentPage
{
ItemViewModel viewModel;
public ItemLocationModel Location { get; set; }
public NewLocationPage()
{
InitializeComponent();
Location = new ItemLocationModel();
BindingContext = viewModel = new ItemViewModel();
BindingContext = this;
viewModel.SubscribeMessages();
}
async void Save_Clicked(object sender, EventArgs e)
{
var location = await Geolocation.GetLastKnownLocationAsync();
Location.Latitude = location.Latitude.ToString();
Location.Longitude = location.Longitude.ToString();
Location.DatePosted = DateTime.Now;
Location.ItemId = ((ItemModel)itemsPicker.SelectedItem).Id;
Location.SecretLocation = secretLocation.IsToggled;
MessagingCenter.Send(this, "AddLocation", Location);
await Navigation.PopModalAsync();
Location = null;
}
async void Cancel_Clicked(object sender, EventArgs e)
{
await Navigation.PopModalAsync();
}
protected override void OnAppearing()
{
viewModel.SubscribeMessages();
base.OnAppearing();
if (viewModel.Items.Count == 0)
viewModel.LoadItemsCommand.Execute(null);
itemsPicker.ItemsSource = viewModel.Items;
}
protected override void OnDisappearing()
{
viewModel.LoadLocationsCommand.Execute(null);
viewModel.UnsubscribeMessages();
base.OnDisappearing();
}
}