I'm using PRISM with a Unity container.
Say I have 3 modules, Module A, Module B, and UserModule. UserModule keeps track of the current user and their privileges, Module A has a View/VM that contains a ComboBox containing all the available users, and Module B has a View/VM that simply displays the current selected user's name.
UserModule registers a singleton instance of UserService which manages the users and provides methods to change the current user.
UserModule.cs
/// Create and register instance of laser service
this.container.RegisterType<IUserService,UserService>(new ContainerControlledLifetimeManager());
Module A - HeaderViewModel.cs
public class HeaderViewModel : BindableBase
{
private readonly IUserService _userService;
private List<IUser> users;
private IUser curUser;
public HeaderViewModel(IUserService userService)
{
_userService = userService;
users = _userService.GetUsers();
curUser = _userService.CurUser;
}
public List<IUser> Users
{
get { return users; }
}
public IUser CurUser
{
get { return curUser; }
set
{
SetProperty<IUser>(ref curUser, value);
_userService.CurUser=curUser;
}
}
}
Module A - HeaderView.xaml
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<TextBlock Text="{Binding CurUser.Name, Mode=TwoWay}"></TextBlock>
<TextBlock Text="Users: "></TextBlock>
<ComboBox ItemsSource="{Binding Users, Mode=TwoWay}" SelectedItem="{Binding CurUser, Mode=TwoWay}" ></ComboBox>
</StackPanel>
All of the above works fine, HeaderView.xaml
loads up with the ComboBox populated, and when I change the user it updates the TextBlock displaying the current User's name, as well as updates the current user object in the UserService singleton.
Now, if I have another View/VM
from Module B that shows the current user name, it should update automatically as well. But, I haven't been able to successfully get this binding to work.
I can post more code if needed, but my real question is if this approach is possible? If each user has certain privileges, and certain controls base their IsEnabled property based on these privileges, it would be awesome to simply update the current user in the singleton UserService object and through simple binding, all the other views/vms
across different models automatically update as well. Is this possible? Or do I need to add some kind of "user changed" event and publish it to all view models who will need to update their UI?
Thanks
Edit 1 Since someone passive aggressively didn't seem to comprehend what I'm asking, I will clarify. If 2 separate Views both use the same singleton service to get data from, is it possible when View1 modifies this data, that View2 atomically updates via xaml binding only? For example, Imagine you have 2 separate views that allow you to change the current user via ComboBox. When I change the user on View1, is it POSSIBLE, via proper binding, for View2 to automatically update it's selected user?
You can do that by making your service notify the rest of the application of changes to the data.
One possibility for that is to make the service implement INotifyPropertyChanged
and then let each view model use the property observer to publish the appropiate notifications for its own properties when it receives a notification from the service.
Depending on the size of the application, you might want to roll out some dedicated CQRS system, but for my desktop apps, the PropertyObserver
normally does very well and gives understandable and refactoring-friendly code.