我正在处理Xamarin Forms。在视图模型之间使用时,退订在MessagingCenter
中不起作用。
我正在尝试退订messagingCenter
中OnDisappear()
上的ContentPage
。我要取消订阅的原因是,当我进行订阅时,它计为两次,并且消息也发送了两次。它最多只能收到1次,与订阅相同。在我的代码下面。
BottomTabsViewModel的订阅位置:
using RCBazaar.Base.ViewModels;
using RCBazaar.Services.Interfaces;
using RCBazaar.ViewModels.Base;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows.Input;
using Xamarin.Forms;
namespace RCBazaar.ViewModels
{
public class BottomTabsViewModel : ViewModelBase
{
public ICommand HomeCommand => new Command(HomeTab_Clicked);
public ICommand CategoriesCommand => new Command(CategoriesTab_Clicked);
public ICommand CartCommand => new Command(CartTab_Clicked);
public ICommand ChatCommand => new Command(ChatTab_Clicked);
private string _badgeText;
private bool _isActiveHome;
public bool IsActiveHome
{
get
{
return _isActiveHome;
}
set
{
_isActiveHome = value;
RaisePropertyChanged(() => IsActiveHome);
}
}
private bool _isActiveCategory;
public bool IsActiveCategory
{
get
{
return _isActiveCategory;
}
set
{
_isActiveCategory = value;
RaisePropertyChanged(() => IsActiveCategory);
}
}
private bool _isActiveCart;
public bool IsActiveCart
{
get
{
return _isActiveCart;
}
set
{
_isActiveCart = value;
RaisePropertyChanged(() => IsActiveCart);
}
}
private bool _isActiveChat;
public bool IsActiveChat
{
get
{
return _isActiveChat;
}
set
{
_isActiveChat = value;
RaisePropertyChanged(() => IsActiveChat);
}
}
public string BadgeText
{
get
{
return _badgeText;
}
set
{
_badgeText = value;
RaisePropertyChanged(() => BadgeText);
}
}
public static string IsSelected { get; set; }
public BottomTabsViewModel()
{
BadgeCount();
if (IsSelected == "Home")
{
ActiveHome();
}
else if (IsSelected == "Category")
{
ActiveCategory();
}
else if (IsSelected == "Cart")
{
ActiveCart();
}
else if (IsSelected == "Chat")
{
ActiveChat();
}
else
{
ActiveHome();
}
}
private void BadgeCount()
{
//Subscriber listen for the specific message. Here getting data for refresh the listView when add item to the database.
MessagingCenter.Subscribe<ProductDetailsViewModel, string>(this, "ShoppingCartCount", (sender, arg) =>
{
try
{
if (arg != null)
{
BadgeText = arg;
}
}
catch (Exception ex)
{
}
});
}
public void HomeTab_Clicked()
{
IsSelected = "Home";
NavigationService.NavigateToAsync<HomeProductsViewModel>();
}
public void CategoriesTab_Clicked()
{
IsSelected = "Category";
NavigationService.NavigateToAsync<MainCategoriesListViewModel>();
}
public void CartTab_Clicked()
{
IsSelected = "Cart";
NavigationService.NavigateToAsync<AccordianViewModel>();
}
public void ChatTab_Clicked()
{
IsSelected = "Chat";
NavigationService.NavigateToAsync<RCBazaarInformationViewModel>("Contact us");
}
public void ActiveHome()
{
IsActiveHome = true;
IsActiveCategory = false;
IsActiveCart = false;
IsActiveChat = false;
}
public void ActiveCategory()
{
IsActiveHome = false;
IsActiveCategory = true;
IsActiveCart = false;
IsActiveChat = false;
}
public void ActiveCart()
{
IsActiveHome = false;
IsActiveCategory = false;
IsActiveCart = true;
IsActiveChat = false;
}
public void ActiveChat()
{
IsActiveHome = false;
IsActiveCategory = false;
IsActiveCart = false;
IsActiveChat = true;
}
}
}
** ProductDetailViewModel发送消息的地方:**
using FFImageLoading.Forms;
using Plugin.Share;
using Plugin.Share.Abstractions;
using RCBazaar.Base.ViewModels;
using RCBazaar.Model.ShoppingCart;
using RCBazaar.Services.Interfaces;
using RCBazaar.Services.Products;
using RCBazaar.ViewModels;
using RCBazaar.Views;
using Rg.Plugins.Popup.Services;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
[assembly: Dependency(typeof(ProductDetailsViewModel))]
namespace RCBazaar.ViewModels
{
public class ProductDetailsViewModel : ViewModelBase
{
private Product _productDetails;
private string _productName;
private long _productStock;
private double _productPrice;
private string _productDescription;
private ObservableCollection<string> _productImage;
private string _productSKU;
private ObservableCollection<CartItem> _basketItems;
private Color _badgeColor;
private long _productId;
private string _overviewColor;
private string _reviewsColor;
private bool _productDescriptionIsVisible;
private long _productRating;
private string _badgeText;
public ProductDetailsViewModel()
{
try
{
BasketItems = new ObservableCollection<CartItem>();
BadgeText = "0";
OverviewColor = "#231f20";//blue color
ReviewsColor = "#DCDCDC";//lightgray
ProductDescriptionIsVisible = true;
ReviewIsVisible = false;
// _navigation = navigation;
var images = new List<string>() { "CourselStaticImage3.jpeg", "CourselStaticImage2.jpeg", "CourselStaticImage1.jpeg", "CourselStaticImage4.jpeg" };
ProductImage = new ObservableCollection<string>(images);
OnRatingChanged();
MyCommand = new Command(() =>
{
Debug.WriteLine("Position selected.");
});
int[] numbers = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
List<WareHouse> wareHouses = new List<WareHouse>()
{
new WareHouse {WarehouseId=1, WareHouseName= "Banglore outlet", Items= numbers },
new WareHouse {WarehouseId=2, WareHouseName= "Pune outlet", Items= numbers },
new WareHouse {WarehouseId=3, WareHouseName= "Mumbai outlet", Items= numbers }
};
ListHeight = wareHouses.Count * 30;
WareHouses = new ObservableCollection<WareHouse>(wareHouses);
Reviews = new ObservableCollection<Review> { new Review { ReviewTitle="title",ReviewText="text",rating=2,IsReviewHelpful=true},
new Review { ReviewTitle="title",ReviewText="text",rating=4,IsReviewHelpful=false},
new Review { ReviewTitle="title",ReviewText="text",rating=0,IsReviewHelpful=true},
new Review { ReviewTitle="title",ReviewText="text",rating=2,IsReviewHelpful=true},
new Review { ReviewTitle="title",ReviewText="text",rating=4,IsReviewHelpful=false},
new Review { ReviewTitle="title",ReviewText="text",rating=0,IsReviewHelpful=true},
new Review { ReviewTitle="title",ReviewText="text",rating=2,IsReviewHelpful=true},
new Review { ReviewTitle="title",ReviewText="text",rating=4,IsReviewHelpful=false},
new Review { ReviewTitle="title",ReviewText="text",rating=0,IsReviewHelpful=true},
};
}
catch (Exception ex)
{
}
}
public class Review
{
public string id { get; set; }
public string ReviewTitle { get; set; }
public string ReviewText { get; set; }
public float rating { get; set; }
public string CreatedDate { get; set; }
public bool IsReviewHelpful { get; set; }
}
private ObservableCollection<Review> _reviews;
public ObservableCollection<Review> Reviews
{
get
{
return _reviews;
}
set
{
_reviews = value;
RaisePropertyChanged(() => Reviews);
}
}
public override async Task InitializeAsync(object navigationData)
{
_productDetails = (Product)navigationData;
ProductName = _productDetails.Name;
ProductStock = _productDetails.Qtyonhand;
ProductPrice = _productDetails.pricelist;
ProductDescription = _productDetails.FullDescription;
ProductRating = _productDetails.RatingSum;
// ProductImage = _productDetails.PictureBinary;
ProductId = _productDetails.ProductId;
ProductSKU = _productDetails.upc;
//// Update Basket/badgecount
//var basket = await _basketService.GetBasketAsync(userInfo.UserId, authToken);
//if (basket != null && basket.Items != null && basket.Items.Any())
//{
// BadgeCount = 0;
// BasketItems.Clear();
// foreach (var basketItem in basket.Items)
// {
// BadgeCount += basketItem.Quantity;
// await AddBasketItemAsync(basketItem);
// }
//}
}
//private async Task AddBasketItemAsync(BasketItem item)
//{
// BasketItems.Add(item);
// await ReCalculateTotalAsync();
//}
public ICommand ItemSelectedCommand => new Command(async () =>
{
try
{
WarehouseItemSelected = null;
}
catch (Exception ex)
{
}
});
public string BadgeText
{
get
{
return _badgeText;
}
set
{
_badgeText = value;
RaisePropertyChanged(() => BadgeText);
}
}
public ICommand AddtoCartCommand => new Command(async(e)=> await AddItemAsync(e));
private async Task AddItemAsync(object e)
{
try
{
var value = int.Parse(BadgeText);
if (value < 10)
{
BadgeText = (++value).ToString();
//BadgeColor = Color.FromHex("#000000");
//await Task.Delay(3000);
//BadgeColor = Color.FromHex("#FF9933");
}
else
BadgeText = "0";
MessagingCenter.Send(this, "ShoppingCartCount", BadgeText);
var selectedItem = (ProductDetailsViewModel)e;
await AddBasketItemAsync(selectedItem);
RaisePropertyChanged(() => BasketItems);
}
catch (Exception ex)
{
await App.Current.MainPage.DisplayAlert("Alert!", "Something went wrong!..", "Ok");
}
}
public Color BadgeColor
{
get
{
return _badgeColor;
}
set
{
_badgeColor = value;
RaisePropertyChanged(() => BadgeColor);
}
}
private async Task AddBasketItemAsync(ProductDetailsViewModel selectedItem)
{
try
{
// BasketItems.Add(selectedItem); this can be used if BasketItems is of type productdetauilsviewmodel
BasketItems.Add(new CartItem { BasketProductId = ProductId, WarehouseDetails = WareHouses });
await ReCalculateTotalAsync();
}
catch (Exception ex)
{
await App.Current.MainPage.DisplayAlert("Alert!", "Something went wrong!..", "Ok");
}
}
private async Task ReCalculateTotalAsync()
{
//Total = 0;
//if (BasketItems == null)
//{
// return;
//}
//foreach (var orderItem in BasketItems)
//{
// Total += (orderItem.Quantity * orderItem.UnitPrice);
//}
//var authToken = _settingsService.AuthAccessToken;
//var userInfo = await _userService.GetUserInfoAsync(authToken);
//await _basketService.UpdateBasketAsync(new CustomerBasket
//{
// BuyerId = userInfo.UserId,
// Items = BasketItems.ToList()
//}, authToken);
}
//public ICommand AddtoCartCommand => new Command(async () =>
//{
// var value = int.Parse(BadgeText);
// if (value < 10)
// BadgeText = (++value).ToString();
// else
// BadgeText = "0";
// MessagingCenter.Send(this, "ShoppingCartCount", BadgeText);
//});
public ObservableCollection<CartItem> BasketItems
{
get { return _basketItems; }
set
{
_basketItems = value;
RaisePropertyChanged(() => BasketItems);
}
}
private int _listHeight;
public int ListHeight
{
get
{
return _listHeight;
}
set
{
_listHeight = value;
RaisePropertyChanged(() => ListHeight);
}
}
private WareHouse _warehouseItemSelected;
public WareHouse WarehouseItemSelected
{
get
{
return _warehouseItemSelected;
}
set
{
_warehouseItemSelected = value;
RaisePropertyChanged(() => WarehouseItemSelected);
}
}
public class WareHouse
{
public int WarehouseId{ get; set; }
public string WareHouseName { get; set; }
public int[] Items { get; set; }
public int quantity { get; set; }
}
private ObservableCollection<WareHouse> _wareHouses;
public ObservableCollection<WareHouse> WareHouses
{
get
{
return _wareHouses;
}
set
{
_wareHouses = value;
RaisePropertyChanged(() => WareHouses);
}
}
public long ProductRating
{
get
{
return _productRating;
}
set
{
_productRating = value;
RaisePropertyChanged(() => ProductRating);
}
}
public long ProductId
{
get
{
return _productId;
}
set
{
_productId = value;
RaisePropertyChanged(() => ProductId);
}
}
public ObservableCollection<string> ProductImage
{
get
{
return _productImage;
}
set
{
_productImage = value;
RaisePropertyChanged(() => ProductImage);
}
}
public string ProductName
{
get
{
return _productName;
}
set
{
_productName = value;
RaisePropertyChanged(() => ProductName);
}
}
public long ProductStock
{
get
{
return _productStock;
}
set
{
_productStock = value;
RaisePropertyChanged(() => ProductStock);
}
}
public double ProductPrice
{
get
{
return _productPrice;
}
set
{
_productPrice = value;
RaisePropertyChanged(() => ProductPrice);
}
}
public string ProductSKU
{
get
{
return _productSKU;
}
set
{
_productSKU = value;
RaisePropertyChanged(() => ProductSKU);
}
}
public string OverviewColor
{
get
{
return _overviewColor;
}
set
{
_overviewColor = value;
RaisePropertyChanged(() => OverviewColor);
}
}
public string ReviewsColor
{
get
{
return _reviewsColor;
}
set
{
_reviewsColor = value;
RaisePropertyChanged(() => ReviewsColor);
}
}
public string ProductDescription
{
get
{
return _productDescription;
}
set
{
_productDescription = value;
RaisePropertyChanged(() => ProductDescription);
}
}
public bool ProductDescriptionIsVisible
{
get
{
return _productDescriptionIsVisible;
}
set
{
_productDescriptionIsVisible = value;
RaisePropertyChanged(() => ProductDescriptionIsVisible);
}
}
private bool _reviewIsVisible;
public bool ReviewIsVisible
{
get
{
return _reviewIsVisible;
}
set
{
_reviewIsVisible = value;
RaisePropertyChanged(() => ReviewIsVisible);
}
}
public Command MyCommand { protected set; get; }
public ICommand AddReviewCommand => new Command(async () =>
{
try
{
// await push.Instance.PopAllAsync();
await PopupNavigation.Instance.PushAsync(new ReviewPopUpView());
//await _navigation.PushAsync(new ReviewPopUpView());
}
catch (Exception ex)
{
}
});
public ICommand ShareCommand => new Command(async () =>
{
try
{
await CrossShare.Current.Share(new ShareMessage
{
Text = "Please download RcBazaar app from playstore",
Title = "Share Product",
Url = "http://rcbazaar.com/product.aspx?productid=6863"
});
}
catch (Exception ex)
{
}
});
private void OnRatingChanged()
{
try
{
//Subscriber listen for the specific message. Here getting data for refresh the listView when add item to the database.
MessagingCenter.Subscribe<ProductsView, float>(this, "ProductsPage", (sender, arg) =>
{
if (arg != null)
{
Rating = arg;
}
});
}
catch (Exception ex)
{
}
}
private float _rating;
public float Rating
{
get
{
return _rating;
}
set
{
_rating = value;
RaisePropertyChanged(() => Rating);
}
}
public ICommand ViewImageCommand => new Command(async (parameter) => await ViewImage((string)parameter));
public async Task ViewImage(string ImageName)
{
try
{
await NavigationService.NavigateToAsync<ImageFullScreenViewModel>(ImageName);
}
catch (Exception ex)
{
}
}
public ICommand OverviewCommand => new Command(async () =>
{
try
{
OverviewColor = "#231f20";//blue color
ReviewsColor = "#DCDCDC";//lightgray
ProductDescriptionIsVisible = true;
ReviewIsVisible = false;
}
catch (Exception ex)
{
}
});
public ICommand ReviewsCommand => new Command(async () =>
{
try
{
OverviewColor = "#DCDCDC";//lightgray
ReviewsColor = "#231f20";//blue color
ProductDescriptionIsVisible = false;
ReviewIsVisible = true;
}
catch (Exception ex)
{
}
});
}
}
主页消失时退订:
using FFImageLoading.Work;
using RCBazaar.CustomRenderer;
using RCBazaar.Helpers;
using RCBazaar.ViewModels;
using RCBazaar.Views.NavigationBarWithSideDrawer;
using Rg.Plugins.Popup.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace RCBazaar.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class HomeView : ContentPage
{
public HomeView()
{
try
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
//BindingContext = new HomeProductsViewModel(this.Navigation);
}
catch (Exception ex)
{
App.Current.MainPage.DisplayAlert(Constants.ConstantKeys.Alert, Constants.ConstantKeys.UIError, Constants.ConstantKeys.Ok);
}
}
protected override void OnDisappearing()
{
base.OnDisappearing();
MessagingCenter.Unsubscribe<SortingOptionsViewModel>(this, "UpdateHomeList");
MessagingCenter.Unsubscribe<ProductDetailsViewModel, string>(this, "ShoppingCartCount");
}
protected override void OnAppearing()
{
base.OnAppearing();
MessagingCenter.Unsubscribe<ProductDetailsViewModel, string>(this, "ShoppingCartCount");
}
}
}
答案 0 :(得分:0)
您要在ViewModel中订阅您想要的 MessagingCenter 事件,但是您要在视图中取消订阅。当用户调用MessagingCenter.Subscribe
时,用户传递了该类的实例,他们希望回调进入。
由于您正在视图中调用取消订阅,并将Views实例传递给取消订阅,因此ViewModel永远都不会被取消订阅,这将导致在您导航回到此页面时产生额外的事件调用。
我建议您不要在视图中调用MessagingCenter.Unsubscribe
,而应在 ViewModel 上调用方法以从MessagingCenter退订。
HomeView.cs
protected override void OnDisappearing()
{
base.OnDisappearing();
ViewModel.Disappearing(); // Method to unsubscribe from MessagingCenter in ViewModel
}
HomeProductsViewModel.cs
public void Disappearing()
{
// Unsubscribe from events here because this is the class where you register them
MessagingCenter.Unsubscribe<SortingOptionsViewModel>(this, "UpdateHomeList");
MessagingCenter.Unsubscribe<ProductDetailsViewModel, string>(this, "ShoppingCartCount");
}
答案 1 :(得分:0)
基于共享代码的一些建议:
OnAppearing
,然后取消订阅OnDisappearing
。目前,您正在订阅构造函数。MessagingCenter.Subscribe
第一个参数是对将要侦听消息的对象的引用,如果您想MessagingCenter.Unsubscribe
,则应使用相同的引用。取消订阅对您不起作用,因为您订阅了视图模型并取消了页面的订阅。有关MessagingCenter
的更多信息可以在the official documentation中找到。