PRISM 6.2 / EntityFramework 6.3.1 / StockTrader UI / UnityContainer
I acutally having a project with PRISM 5.0.0 and want to update to PRISM 6.2. The project runs fine on 5.0.0, but when I'm updating to 6.2 I got the following problem with the InteractionRequest.
When I navigate to a view/viewmodel with Notifications for the first time, everything works and I can handle the InteractionRequests as usual. If I navigate back and navigate to the view again with a new object, the InteractionsRequest raised the notification twice. (...navigating back and go to again -> raised three times and so on).
In some reasons, the message "This Visual is not connected to a PresentationSource" will occur.
I figure out, that the _invocationCount and _invocationList on the InteractionRequest will not be set to "0"/"null" with PRISM 6.2. So, i think the InteractionRequest will call the notification more than one time. Attached, are screenshots from PRISM 5 and PRISM 6.2.
How can I handle this and solve the problem. In my opinion, it's not a big thing but I actually spent a lot of time to find a solution. Thanks...
2017.02.22 Added Sourccode. Software is used to handle devices in datacenters. I deleted all unnecessary sourcecode, but with these files the problem still occur. Perhaps this is a try to find my issue....
Rackmodule.cs -> Initialize Module Rack
public class RackModule : IModule
{
private readonly IRegionManager _regionManager;
private readonly IUnityContainer _container;
public RackModule(IRegionManager regionManager, IUnityContainer container)
{
_regionManager = regionManager;
_container = container;
}
public void Initialize()
{
_container.RegisterType<IRackViewModel, RackViewModel>(new ContainerControlledLifetimeManager());
_container.RegisterType<IRackToolbarViewModel, RackToolbarViewModel>(new ContainerControlledLifetimeManager());
_container.RegisterType<IRackStatusbarViewModel, RackStatusbarViewModel>(new ContainerControlledLifetimeManager());
_container.RegisterType<IRackSummaryViewModel, RackSummaryViewModel>(new ContainerControlledLifetimeManager());
_container.RegisterType<IGeneralDataViewModel, GeneralDataViewModel>(new ContainerControlledLifetimeManager());
_container.RegisterType<IPlanDataViewModel, PlanDataViewModel>(new ContainerControlledLifetimeManager());
_container.RegisterType<IRackDataViewModel, RackDataViewModel>(new ContainerControlledLifetimeManager());
_container.RegisterType<Object, GeneralDataView>(typeof(GeneralDataView).FullName);
IRegion region = this._regionManager.Regions["MainRegion"];
var rackView = _container.Resolve<RackView>();
region.Add(rackView, "RackView");
region.Activate(rackView);
IRegion toolbarregion = this._regionManager.Regions["RackToolbarRegion"];
var toolbarView = _container.Resolve<RackToolbarView>();
toolbarregion.Add(toolbarView, "RackToolbarView");
toolbarregion.Activate(toolbarView);
IRegion statusbarregion = this._regionManager.Regions["RackStatusbarRegion"];
var statusbarView = _container.Resolve<RackStatusbarView>();
statusbarregion.Add(statusbarView, "RackStatusbarView");
statusbarregion.Activate(statusbarView);
_container.RegisterType<Object, RackSummaryView>(typeof(RackSummaryView).FullName);
_regionManager.RequestNavigate(RegionNames.RackContentRegion, typeof(RackSummaryView).FullName);
}
}
RackSummaryViewModel.cs -> Overview of racks. Go to RackDataView, when click on object
public class RackSummaryViewModel : BindableBase, IRackSummaryViewModel
{
private readonly IRegionManager _regionManager;
private readonly IEventAggregator _eventAggregator;
private readonly IUnityContainer _container;
public DelegateCommand<SearchEventArgs> OnSearch { get; private set; }
public DelegateCommand AdvancedRackSearchCommand { get; private set; }
public InteractionRequest<AdvancedRackSearchNotification> AdvancedSearchRequest { get; private set; }
private ObservableCollection<RackSummaryEntry> _racks;
public ObservableCollection<RackSummaryEntry> Racks
{
get { return _racks; }
private set {SetProperty(ref _racks, value);}
}
private RackSummaryEntry _currentRack;
public RackSummaryEntry CurrentRack
{
get { return _currentRack; }
set
{
if (SetProperty(ref _currentRack, value))
{
if (_currentRack != null)
{
var parameters = new NavigationParameters();
parameters.Add("RackID", _currentRack.PrimaryKey.ToString(GuidNumericFormatSpecifier));
_container.RegisterType<Object, RackDataView>(typeof(RackDataView).FullName);
_regionManager.RequestNavigate(RegionNames.RackContentRegion, new Uri(typeof(RackDataView).FullName + parameters, UriKind.Relative));
}
}
}
}
private const string GuidNumericFormatSpecifier = "N";
public RackSummaryViewModel(IEventAggregator eventAggregator, IRegionManager regionManager, IUnityContainer container)
{
_regionManager = regionManager;
_eventAggregator = eventAggregator;
_container = container;
ISessionFactory factory = new SessionFactory();
container.RegisterType<IRepository, Repository>(new InjectionConstructor(factory.CurrentUoW));
IUnitOfWork unitOfWork = factory.CurrentUoW;
IRepository localrepository = new Repository(unitOfWork);
var query = localrepository.GetList<DMS.Domain.Domain.Rack>();
Racks = new ObservableCollection<RackSummaryEntry>(query
.Select(x => new RackSummaryEntry
{
PrimaryKey = x.PrimaryKey,
Country = x.Location.Address.Country,
City = x.Location.Address.City,
Street = x.Location.Address.Street,
Building = x.Location.BuildingName,
RoomName = x.Location.RoomName,
RackName = x.RackName,
RackHeight = x.RackHeight
}).ToList());
}
}
RackDataViewModel.cs -> Only Button "Save" und "Go Back"
public class RackDataViewModel : BindableBase, IRackDataViewModel, INavigationAware, IRegionMemberLifetime
{
private IRegionNavigationJournal _navigationJournal;
private readonly IRegionManager _regionManager;
private readonly IUnityContainer _container;
private readonly IEventAggregator _eventAggregator;
public DelegateCommand GoBackCommand { get; private set; }
public DelegateCommand SaveCommand { get; private set; }
public InteractionRequest<INotification> SaveNotificationRequest { get; private set; }
private const string RackIdKey = "RackID";
private const string EType = "EditType";
private const string GuidNumericFormatSpecifier = "N";
public DMS.Domain.Domain.Rack rack;
// [InjectionConstructor] check if necessary
public RackDataViewModel(IRegionManager regionManager, IRegionNavigationJournal navigationJournal, IUnityContainer container, IEventAggregator eventAggregator, ILoggerFactory logFactory)
{
_regionManager = regionManager;
_navigationJournal = navigationJournal;
_container = container;
_eventAggregator = eventAggregator;
GoBackCommand = new DelegateCommand(OnGoBackExecute);
SaveCommand = new DelegateCommand(OnSaveExecute);
SaveNotificationRequest = new InteractionRequest<INotification>();
}
private void OnGoBackExecute()
{
if (_navigationJournal != null)
{
while (_navigationJournal.CanGoBack)
_navigationJournal.GoBack();
_regionManager.Regions.Remove(RegionNames.RackGeneralDataRegion);
}
}
private void OnSaveExecute()
{
SaveNotificationRequest.Raise(new Notification { Content = "Save changes submitted", Title = "Save changes" });
}
public bool KeepAlive
{
get { return false; }
}
private Guid? GetRequestedRackId(NavigationContext navigationContext)
{
var rack = navigationContext.Parameters[RackIdKey];
Guid rackId;
if (rack != null)
{
if (rack is Guid)
rackId = (Guid)rack;
else
rackId = Guid.Parse(rack.ToString());
return rackId;
}
return null;
}
bool INavigationAware.IsNavigationTarget(NavigationContext navigationContext)
{
var type = navigationContext.Parameters[EType];
if (rack == null || ((string)type) == "New")
return true;
var requestedRackId = GetRequestedRackId(navigationContext);
return requestedRackId.HasValue && requestedRackId.Value == rack.PrimaryKey;
}
void INavigationAware.OnNavigatedFrom(NavigationContext navigationContext)
{
}
void INavigationAware.OnNavigatedTo(NavigationContext navigationContext)
{
Guid? rackId;
NavigationParameters parameters = new NavigationParameters();
string key = navigationContext.Parameters[RackIdKey].ToString();
rackId = GetRequestedRackId(navigationContext);
parameters = navigationContext.Parameters;
_regionManager.RequestNavigate(RegionNames.RackGeneralDataRegion, new Uri(typeof(GeneralDataView).FullName + parameters, UriKind.Relative));
_navigationJournal = navigationContext.NavigationService.Journal;
}
}
GeneralDataViewModel.cs -> Is in region of RackDataView with the data of the racks
public class GeneralDataViewModel : BindableBase, IGeneralDataViewModel, INavigationAware
{
private IRegionNavigationJournal _navigationJournal;
private readonly IRegionManager _regionManager;
private readonly IRepository _repository;
private const string RackIdKey = "RackID";
public DMS.Domain.Domain.Rack Rack { get; set; }
public List<Location> Locations { get; set; }
public GeneralDataViewModel(IRegionManager regionManager, IRepository repository)
{
_regionManager = regionManager;
_repository = repository;
}
private Guid? GetRequestedRackId(NavigationContext navigationContext)
{
var rack = navigationContext.Parameters[RackIdKey];
Guid rackId;
if (rack != null)
{
if (rack is Guid)
rackId = (Guid)rack;
else
rackId = Guid.Parse(rack.ToString());
return rackId;
}
return null;
}
bool INavigationAware.IsNavigationTarget(NavigationContext navigationContext)
{
if (Rack == null)
return true;
var requestedRackId = GetRequestedRackId(navigationContext);
return requestedRackId.HasValue && requestedRackId.Value == Rack.PrimaryKey;
}
void INavigationAware.OnNavigatedFrom(NavigationContext navigationContext)
{
// Intentionally not implemented.
}
void INavigationAware.OnNavigatedTo(NavigationContext navigationContext)
{
var rackId = GetRequestedRackId(navigationContext);
Rack = _repository.GetEntity<DMS.Domain.Domain.Rack>(rackId);
_navigationJournal = navigationContext.NavigationService.Journal;
}
}