[英]Changing TabbedPage binding property from a (different) class - Xamarin.Forms
My TabbedPage
uses a Binding Property
, which is defined in the tabbed page's ViewModel
, for showing a Badge
text.我的
TabbedPage
使用在选项卡式页面的ViewModel
中定义的Binding Property
来显示Badge
文本。
I am setting the badge property when initializing the view (actually when it (re)appears).我在初始化视图时设置了 badge 属性(实际上是在它(重新)出现时)。 However, sometimes the badge text is changing from outside of my ViewModel(s), this is because I have a
SignalR
method which is called when a new message is being added by another application.但是,有时徽章文本会从我的 ViewModel(s) 外部发生变化,这是因为我有一个
SignalR
方法,当另一个应用程序添加新消息时会调用该方法。
Though, when this happens the OnAppearing
method of my tabbed viewmodel is obviously not called.但是,当这种情况发生时,我的选项卡式视图模型的
OnAppearing
方法显然不会被调用。 So the question is, how can I 'notify' the tabbedpage viewmodel that the badge text should be changed.所以问题是,我如何“通知”标签页视图模型应该更改徽章文本。
I think the (best) way to do this is using somekind of Event.我认为(最好的)方法是使用某种事件。 Since all of my
ViewModels
inherit from a 'ViewModelBase' I could implement the event notification / change in the ViewModelBase
and override the property in my TabbedPage ViewModel.由于我的所有
ViewModels
都继承自“ViewModelBase”,因此我可以在ViewModelBase
中实现事件通知/更改并覆盖我的 TabbedPage ViewModel 中的属性。 Though, sadly my knowledge about using Events
/ EventArgs
is limited and the stuff I found about it is not working.不过,遗憾的是,我对使用
Events
/ EventArgs
的了解有限,而且我发现的关于它的东西不起作用。
Is using EventArgs
the best way to solve this problem?使用
EventArgs
是解决此问题的最佳方法吗? And if so, could anyone give any pointers how to implement it properly.如果是这样,任何人都可以提供任何指示如何正确实施它。
*On a side-note, I am also using Prism *附带说明,我也在使用 Prism
My TabbedPage ViewModel:我的标签页视图模型:
public class RootTabbedViewModel : ViewModelBase, IPageLifecycleAware
{
private readonly INavigationService _navigationService;
private int _messageCount;
public RootTabbedViewModel(INavigationService navigationService)
: base(navigationService)
{
_navigationService = navigationService;
}
public int MessageCount
{
get { return _messageCount; }
set { SetProperty(ref _messageCount, value); }
}
public void OnDisappearing()
{
}
void IPageLifecycleAware.OnAppearing()
{
// (omitted) Logic for setting the MessageCount property
}
}
ViewModelVase:视图模型花瓶:
public class ViewModelBase : BindableBase, IInitialize, IInitializeAsync, INavigationAware, IDestructible, IActiveAware
{
public event EventHandler MessageAddedEventArgs; // this should be used to trigger the MessageCount change..
protected INavigationService NavigationService { get; private set; }
public ViewModelBase(INavigationService navigationService)
{
NavigationService = navigationService;
Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged;
IsNotConnected = Connectivity.NetworkAccess != NetworkAccess.Internet;
}
private bool _isNotConnected;
public bool IsNotConnected
{
get { return _isNotConnected; }
set { SetProperty(ref _isNotConnected, value); }
}
~ViewModelBase()
{
Connectivity.ConnectivityChanged -= Connectivity_ConnectivityChanged;
}
async void Connectivity_ConnectivityChanged(object sender, ConnectivityChangedEventArgs e)
{
IsNotConnected = e.NetworkAccess != NetworkAccess.Internet;
if (IsNotConnected == false)
{
await DataHubService.Connect();
}
}
public virtual void Initialize(INavigationParameters parameters)
{
}
public virtual void OnNavigatedFrom(INavigationParameters parameters)
{
}
public virtual void OnNavigatedTo(INavigationParameters parameters)
{
}
public virtual void Destroy()
{
}
public virtual Task InitializeAsync(INavigationParameters parameters)
{
return Task.CompletedTask;
}
}
SignalR Datahub which should trigger the event: SignalR Datahub 应该触发事件:
public static class DataHubService2
{
// .. omitted some other SignalR specific code
public static async Task Connect()
{
try
{
GetInstanse();
hubConnection.On<Messages>("ReceiveMessage", async (message) =>
{
if(message != null)
{
// event that message count has changed should be triggered here..
}
});
}
catch (Exception ex)
{
// ...
}
}
}
As pointed out by @Jason, this specific problem is a good use case for using the MessagingCenter.正如@Jason 所指出的,这个特定问题是使用 MessagingCenter 的一个很好的用例。
In the end the implementation looks as following:最后,实现如下所示:
public static class DataHubService2
{
// .. omitted some other SignalR specific code
public static async Task Connect()
{
try
{
GetInstanse();
hubConnection.On<Messages>("ReceiveMessage", async (message) =>
{
if(message != null)
{
MessagingCenter.Send("UpdateMessageCount", "Update");
}
});
}
catch (Exception ex)
{
// ...
}
}
}
public class RootTabbedViewModel : ViewModelBase, IPageLifecycleAware
{
private readonly INavigationService _navigationService;
private int _messageCount;
public RootTabbedViewModel(INavigationService navigationService)
: base(navigationService)
{
_navigationService = navigationService;
MessagingCenter.Subscribe<string>("UpdateMessageCount", "Update", async (a) =>
{
await UpdateMessageCount();
});
}
public int MessageCount
{
get { return _messageCount; }
set { SetProperty(ref _messageCount, value); }
}
public void OnDisappearing()
{
}
void IPageLifecycleAware.OnAppearing()
{
UpdateMessageCount();
}
async Task UpdateMessageCount()
{
int messageCount = await App.Database.GetNewMessageCountAsync();
MessageCount = messageCount.ToString();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.