【问题标题】:How to update badge counter in Parent tab page xamarin forms如何在父标签页 xamarin 表单中更新徽章计数器
【发布时间】:2019-10-22 07:37:15
【问题描述】:

我有一个使用标签页的应用程序,在父标签页的 xaml 中 我填充了所有其他标签页,我有一个绑定到父标签页的视图模型和每个其他标签页的视图模型。我在其中一个标签上有一个徽章,它有一个显示有多少消息的计数器。 我在更新计数器时遇到问题。

所以我有一个调用来从数据库中检索未读消息的数量,这些消息在应用加载时填充到计数器中。当我导航以查看消息时,它会更新已读取消息的数据库,然后使用 popasync 导航回选项卡式页面,然后拉动刷新,执行调用以获取已读取的消息量但未更新计数器,如果我在 GetCounter 方法上设置一个断点,我会看到它正在用正确的数量更新计数器,但徽章上没有改变。

希望这是有道理的。

如果有人可以提供帮助,我将不胜感激。

母版标签页:

<NavigationPage Title="Message" Icon="email.png"  plugin:TabBadge.BadgeText="{Binding counter}" 
             plugin:TabBadge.BadgeColor="Red"
             plugin:TabBadge.BadgePosition="PositionTopRight"
             plugin:TabBadge.BadgeTextColor="Green">
    <x:Arguments>
        <local:MessagePage  BindingContext="{Binding messages}" />
    </x:Arguments>
</NavigationPage>



public partial class MasterTabPage : TabbedPage
{
    Master_PageViewModel vm;
    public MasterTabPage ()
    {
        InitializeComponent ();
        this.BindingContext = vm = new Master_PageViewModel(Navigation);
    }
}

母版标签页视图模型:

 public class Master_PageViewModel : INotifyPropertyChanged
{
    INavigation Navigation;
    private int _counter;
    public int counter
    {
        get => _counter;
        set
        {
            _counter = value;
            OnPropertyChanged(nameof(counter));

        }
    }
    public MessagePageViewModel messages { get; set; }
    public Master_PageViewModel(INavigation navigation)
    {
        Navigation = navigation;
        messages = new MessagePageViewModel(Navigation);
        Init();
        counter = 0;
    }
    public async void Init()
    {
        await GetCounter();
    }
    public async Task GetCounter()
    {
        try
        {
            using (HttpClient client = new HttpClient())
            {
                List<MessageModel> msg = new List<MessageModel>();

                using (HttpResponseMessage response = await client.GetAsync("http://localhost:53665/api/GetMessagesCount/Id=" + 2 + "/" ))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        using (HttpContent content = response.Content)
                        {
                            var textresponse = await content.ReadAsStringAsync();
                            var json = JsonConvert.DeserializeObject<List<MessageModel>>(textresponse);
                            foreach (var i in json)
                            {
                                msg.Add(new MessageModel
                                {
                                    msgCounter = i.msgCounter,
                                });
                            }
                            counter = msg[0].msgCounter;
                        }
                    }
                    else
                    {

                    }
                }
            }
        }
        catch (Exception)
        {

        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

消息选项卡视图模型:

public class MessagePageViewModel : BaseViewModel
{

    public ICommand MessageDetailsCommand { get; set; }
    INavigation Navigation;

    private ObservableCollection<MessageModel> _messagesList;
    public ObservableCollection<MessageModel> MessagesList
    {
        get { return _messagesList; }
        set
        {
            if (_messagesList != value)
            {
                _messagesList = value;
            }
        }
    }

    public ICommand ReloadCommand { get; set; }
    public ICommand RefreshCommand
    {
        get
        {
            return new Command(async () =>
            {
                await GetMessages();
                Master_PageViewModel vm = new Master_PageViewModel(Navigation,multiMediaPickerService);
                await vm.GetCounter();
            });
        }
    }

    bool _isBusy;
    public bool IsBusy
    {
        get { return _isBusy; }
        set
        {
            _isBusy = value;

        }
    }
    public MessagePageViewModel(INavigation navigation)
    {


        ReloadCommand = new Command(async () => await ReloadPage());

        Navigation = navigation;
        MessageDetailsCommand = new Command(async (object obj) => await MessageDetails(obj));
        Initialize();

    }

    private async void Initialize()
    {

        await GetMessages();

    }

    private async Task ReloadPage()
    {
        await GetMessages();
    }


    public async Task GetMessages()
    {
        List<MessageModel> msg = new List<MessageModel>
           .........
        MessagesList = new ObservableCollection<MessageModel>(msg);

    }

    private async Task MessageDetails(object obj)
    {
        var item = (obj as MessageModel);

        await Navigation.PushAsync(new MessageDetailsPage(....));
    }

    }
    }
}

【问题讨论】:

    标签: c# xamarin.forms mvvmcross badge


    【解决方案1】:

    这是因为您在 RefreshCommand 中创建了 Master_PageViewModel 的新实例。它不是父标签页的绑定上下文,因此即使 GetCounter 已被触发,标签的徽章也不会更新。

    您必须将父选项卡式视图模型传递给您的MessagePageViewModel,例如:

    public Master_PageViewModel(INavigation navigation)
    {
        Navigation = navigation;
        messages = new MessagePageViewModel(Navigation, this);
        Init();
        counter = 0;
    }
    

    并更改您的消息页面视图模型的构造函数:

    Master_PageViewModel parentViewModel
    public MessagePageViewModel(INavigation navigation, Master_PageViewModel viewModel)
    {
        ReloadCommand = new Command(async () => await ReloadPage());
    
        Navigation = navigation;
        parentViewModel = viewModel;
    
        // ...
    }
    

    最后,触发刷新命令中的方法:

    public ICommand RefreshCommand
    {
        get
        {
            return new Command(async () =>
            {
                await GetMessages();
                await parentViewModel.GetCounter();
            });
        }
    }
    

    此外,我注意到您的MessagePageViewModel 使用了父选项卡式视图模型的导航。我认为这不是一个好方法,因为它有自己的 NavigationPage,因此它应该使用自己的导航而不是父导航。

    【讨论】:

    • 非常感谢陆陆,感谢您抽出时间帮助我解决我的问题。
    • @BryteNyte 这是我的荣幸。
    猜你喜欢
    • 2017-10-06
    • 1970-01-01
    • 2015-07-02
    • 2019-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-06
    • 2018-08-03
    • 2017-12-09
    相关资源
    最近更新 更多