I Have Two ComboBoxes for example Country and State where State ComboBox's ItemSource depends on Selected Country of First ComboBox.
Country and State Properties are defined in separate CountryModel(CountryID,CountryName) and StateModel(CountryID,StateID,StateName).
Now there is the Model "UserModel" is like :
public class UserModel:ViewModelBase
{
private string _userName;
public string UserName
{
get { return _userName; }
set { _userName = value; OnPropertyChanged("UserName"); }
}
private long _stateID;
public long StateID
{
get { return _stateID; }
set { _stateID = value; OnPropertyChanged("StateID"); }
}
private int _countryID;
public int CountryID
{
get { return _countryID; }
set { _countryID = value; OnPropertyChanged("CountryID"); }
}
}
It has a Service "UserModelService" for populating :
public class UserModelService
{
public UserModelService()
{
}
public ObservableCollection<UserModel> GetUserList()
{...}
public ObservableCollection<CountryModel> GetCountryList()
{...}
public ObservableCollection<StateModel> GetStateList()
{...}
}
Now The UserViewModel is Like:
public class UserViewModel:ViewModelBase,IPageViewModel
{
UserModelService modelService;
public UserViewModel()
{
modelService = new UserModelService();
GetData();
}
private void GetData()
{
UserList = modelService.GetUserList();
CountryList = modelService.GetCountryList();
StateList = modelService.GetStateList();
}
private UserModel _currentUser=new UserModel();
public UserModel CurrentUser
{
get { return _currentUser; }
set
{
if (value == _currentUser) return;
_currentUser = value; OnPropertyChanged("CurrentUser");
}
}
private ObservableCollection<UserModel> _userList;
public ObservableCollection<UserModel> UserList
{
get { return _userList; }
set
{
if (value == _userList) return;
_userList = value;
OnPropertyChanged("UserList");
}
}
private ObservableCollection<CountryModel> _countryList;
public ObservableCollection<CountryModel> CountryList
{
get { return _countryList; }
set { _countryList = value; OnPropertyChanged("CountryList"); }
}
private ObservableCollection<StateModel> _stateList;
public ObservableCollection<StateModel> StateList
{
get { return _stateList; }
set
{
_stateList = value;
OnPropertyChanged("StateList");
}
}
}
Now the Country and State ComboBox's ItemSource is binded to UserViewModels "CountryList" and "StateList" respectively. In this scenario how to I repopulate StateList OnPropertyChange of CurrentUser.CountryID?
EDIT: I Solved it by introducing separate property for Selected Country and OnPropertyChanged CurrentUser.CountryID=selectedCountry. Thanks
Handle the PropertyChanged event for the current user:
public UserModel CurrentUser
{
get { return _currentUser; }
set
{
if (value == _currentUser)
return;
if (_currentUser != null)
_currentUser.PropertyChanged -= OnCurrentUserPropertyChanged;
_currentUser = value;
if (_currentUser != null)
_currentUser.PropertyChanged += OnCurrentUserPropertyChanged;
OnPropertyChanged("CurrentUser");
}
}
private void OnCurrentUserPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(UserModel.CountryID))
{
UserModel userModel = (UserModel)sender;
var states = ...; //get states by userModel.CountryID
StateList = states;
}
}
I am using prism 6 and on my application I have modules. I want to navigate to different views on different modules and I am using INavigationAware Interface. I can call OnNavigatedFrom every time I am navigating away from current view but when I enter a new view OnNavigatedTo is not fired which is giving me a headache. I will post my code from bootstrap to viewmodel for one module.
Bootstraper.cs
public class Bootstrapper : UnityBootstrapper
{
#region Members
private ILog _logger;
#endregion
#region Properties
#endregion
#region Methods
protected override DependencyObject CreateShell()
{
_logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
RegisterTypes();
return Container.Resolve<AppShell>();
}
protected override void InitializeShell()
{
App.Current.MainWindow = (Window)this.Shell;
App.Current.MainWindow.Show();
}
protected void RegisterTypes()
{
Container.RegisterType<ILogger, Log4NetLogger>(new InjectionConstructor(_logger));
Container.RegisterType<IEncryption, SymmetricEncryption>();
Container.RegisterType<IGetSavviUow, GetSavviUowMock>();
Container.RegisterType<ICustomAuthentication, MockCustomAuthentication>();
Container.RegisterType<ICustomPrincipal, CustomPrincipal>();
Container.RegisterType<IIdNumberValidation, IdNumberValidation>();
Container.RegisterType<ISalesValidation, SalesValidation>();
AutoMapperConfig.RegisterMappings();
}
protected override void ConfigureModuleCatalog()
{
ModuleCatalog.AddModule(new ModuleInfo()
{
InitializationMode = InitializationMode.WhenAvailable,
ModuleType = typeof(LoginModuleDefinition).AssemblyQualifiedName,
ModuleName = typeof(LoginModuleDefinition).Name
});
ModuleCatalog.AddModule(new ModuleInfo()
{
InitializationMode = InitializationMode.OnDemand,
ModuleType = typeof(AgentQueueModuleDefinition).AssemblyQualifiedName,
ModuleName = typeof(AgentQueueModuleDefinition).Name
});
ModuleCatalog.AddModule(new ModuleInfo()
{
InitializationMode = InitializationMode.OnDemand,
ModuleType = typeof(PreQualificationModuleDefinition).AssemblyQualifiedName,
ModuleName = typeof(PreQualificationModuleDefinition).Name
});
ModuleCatalog.AddModule(new ModuleInfo()
{
InitializationMode = InitializationMode.OnDemand,
ModuleType = typeof(SearchModuleDefinition).AssemblyQualifiedName,
ModuleName = typeof(SearchModuleDefinition).Name
});
ModuleCatalog.AddModule(new ModuleInfo()
{
InitializationMode = InitializationMode.OnDemand,
ModuleType = typeof(PlanSelectionModuleDefinition).AssemblyQualifiedName,
ModuleName = typeof(PlanSelectionModuleDefinition).Name
});
ModuleCatalog.AddModule(new ModuleInfo()
{
InitializationMode = InitializationMode.OnDemand,
ModuleType = typeof(BenefitsScriptModuleDefinition).AssemblyQualifiedName,
ModuleName = typeof(BenefitsScriptModuleDefinition).Name
});
ModuleCatalog.AddModule(new ModuleInfo()
{
InitializationMode = InitializationMode.OnDemand,
ModuleType = typeof(PersonalInfoModuleDefinition).AssemblyQualifiedName,
ModuleName = typeof(PersonalInfoModuleDefinition).Name
});
}
protected override void InitializeModules()
{
base.InitializeModules();
}
#endregion
#region Constructors
#endregion
}
ShellViewModel.cs
public class ShellViewModel : ViewModelBase
{
#region Members
private string _username;
private bool _isLoggedIn;
private string _viewName;
private bool _canCreateNewMembership;
private bool _canUpgrade;
private bool _canReinstate;
private bool _canContinue;
private ILogger _logger;
private IModuleManager _moduleManager;
private IRegionManager _regionManager;
private Guid _agentRefId;
#endregion
#region Properties
public string Username
{
get { return _username; }
set
{
SetProperty(ref _username, value);
}
}
public bool IsLoggedIn
{
get { return _isLoggedIn; }
set { SetProperty(ref _isLoggedIn, value); }
}
public string ViewName
{
get { return _viewName; }
set { SetProperty(ref _viewName, value); }
}
#endregion
#region Methods
private void InitDelegateCommands()
{
this.LogoutCommand = new DelegateCommand(Logout);
this.ContinueCommand = new DelegateCommand<string>(Continue, CanContinue);
this.CreateNewMembershipCommand = new DelegateCommand(CreateNewMembership, CanCreateNewMembership);
this.ExitApplicationCommand = new DelegateCommand(ExitApplication);
this.ReinstateCommand = new DelegateCommand(Reinstate, CanReinstate);
this.SaveAndExitCommand = new DelegateCommand(SaveAndExit);
this.SaveProgressCommand = new DelegateCommand(Save);
this.SetCallBackCommand = new DelegateCommand(SetCallBack);
this.UpgradeCommand = new DelegateCommand(Upgrade, CanUpgrade);
}
private bool CanContinue(string navigatingTo)
{
this.NavigatingToView = navigatingTo;
return _canContinue;
}
private void Continue(string currentView)
{
this.Aggregator.GetEvent<ContinueEvent>().Publish(
this.ViewNavigationList
.First(x =>
x.CurrentView == currentView).RequestedView);
}
private bool CanUpgrade()
{
return _canUpgrade;
}
private void Upgrade()
{
this.Aggregator.GetEvent<UpgradeEvent>().Publish(_agentRefId);
}
private void Logout()
{
ICustomPrincipal customPrincipal = Thread.CurrentPrincipal as ICustomPrincipal;
if (customPrincipal != null)
{
customPrincipal.CustomIdentity = new AnonymousIdentity();
this.Username = string.Empty;
this.IsLoggedIn = false;
ShowView(ModuleViewConstants.LoginView);
}
}
private void SetCallBack()
{
this.Aggregator.GetEvent<SetCallBackEvent>().Publish(_agentRefId);
}
private void Save()
{
this.Aggregator.GetEvent<SaveEvent>().Publish(_agentRefId);
}
private void SaveAndExit()
{
this.Aggregator.GetEvent<SaveEvent>().Publish(_agentRefId);
}
private bool CanReinstate()
{
return _canReinstate;
}
private void Reinstate()
{
this.Aggregator.GetEvent<ContinueEvent>().Publish(ModuleViewConstants.PlanSelectionView);
}
private bool CanCreateNewMembership()
{
return _canCreateNewMembership;
}
private void CreateNewMembership()
{
this.Aggregator.GetEvent<ContinueEvent>().Publish(ModuleViewConstants.PlanSelectionView);
}
private void ExitApplication()
{
this.Aggregator.GetEvent<ExitApplicationEvent>().Publish(_agentRefId);
}
private void OnLoggedOn(LoggedOnArgument args)
{
this.Username = args.Username;
this.IsLoggedIn = args.IsLoggedOn;
_agentRefId = args.AgentRefId;
LoadModules();
_regionManager.Regions[RegionConstants.QueueRegion].Context = _agentRefId;
ShowView(ModuleViewConstants.PreQualificationView);
}
private void LoadModules()
{
_moduleManager.LoadModule(typeof(AgentQueueModuleDefinition).Name);
_moduleManager.LoadModule(typeof(SearchModuleDefinition).Name);
_moduleManager.LoadModule(typeof(PreQualificationModuleDefinition).Name);
_moduleManager.LoadModule(typeof(PlanSelectionModuleDefinition).Name);
_moduleManager.LoadModule(typeof(BenefitsScriptModuleDefinition).Name);
_moduleManager.LoadModule(typeof(PersonalInfoModuleDefinition).Name);
}
private void ShowView(string view)
{
this.ViewName = view;
this.CurrentView = view;
_regionManager.RequestNavigate(
RegionConstants.OperationsRegion,
new Uri(view, UriKind.Relative));
}
private void AssingCanCreateNewMembership(bool canCreateMembership)
{
_canCreateNewMembership = canCreateMembership;
CreateNewMembershipCommand.RaiseCanExecuteChanged();
}
private void AssignCanContinue(bool canContinue)
{
_canContinue = canContinue;
ContinueCommand.RaiseCanExecuteChanged();
}
private void AssignCanUpgrade(bool canUpgrade)
{
_canUpgrade = canUpgrade;
UpgradeCommand.RaiseCanExecuteChanged();
}
private void AssignCanReinstate(bool canReinstate)
{
_canReinstate = canReinstate;
ReinstateCommand.RaiseCanExecuteChanged();
}
private void EventSubscriptions()
{
this.Aggregator.GetEvent<LoggedOnEvent>().Subscribe(OnLoggedOn);
this.Aggregator.GetEvent<ShowViewEvent>().Subscribe(ShowView);
this.Aggregator.GetEvent<CanCreateNewMembership>().Subscribe(AssingCanCreateNewMembership);
this.Aggregator.GetEvent<CanContinueEvent>().Subscribe(AssignCanContinue);
this.Aggregator.GetEvent<CanUpgradeEvent>().Subscribe(AssignCanUpgrade);
this.Aggregator.GetEvent<CanReinstateEvent>().Subscribe(AssignCanReinstate);
}
#endregion
#region Commands
public DelegateCommand LogoutCommand { get; set; }
public DelegateCommand ExitApplicationCommand { get; set; }
public DelegateCommand<string> ContinueCommand { get; set; }
public DelegateCommand SaveProgressCommand { get; set; }
public DelegateCommand SetCallBackCommand { get; set; }
public DelegateCommand SaveAndExitCommand { get; set; }
public DelegateCommand CreateNewMembershipCommand { get; set; }
public DelegateCommand ReinstateCommand { get; set; }
public DelegateCommand UpgradeCommand { get; set; }
#endregion
#region Events
#endregion
#region Construction
public ShellViewModel(
IRegionManager regionManager,
IUnityContainer container,
IEventAggregator aggregator,
IModuleManager moduleManager,
ILogger logger)
: base(aggregator, container)
{
_logger = logger;
_logger.Info("Starting Shell");
_moduleManager = moduleManager;
_regionManager = regionManager;
InitDelegateCommands();
EventSubscriptions();
}
#endregion
}
PreQualificationModule
PreQualificationModuleDefinition.cs
public class PreQualificationModuleDefinition : IModule
{
#region Members
private IRegionManager _regionManager;
private IUnityContainer _container;
#endregion
#region Properties
#endregion
#region Methods
public void Initialize()
{
_container.RegisterType<object, PreQualificationView>(ModuleViewConstants.PreQualificationView);
_regionManager.RegisterViewWithRegion(RegionConstants.OperationsRegion, typeof(PreQualificationView));
}
#endregion
#region Constructors
public PreQualificationModuleDefinition(
IRegionManager regionManager,
IUnityContainer container)
{
_regionManager = regionManager;
_container = container;
}
#endregion
}
PreQualificationViewModel.cs
public class PreQualificationViewModel : ViewModelBase, INavigationAware
{
#region Members
private string _name;
private int _selectedIdType;
private string _contactNumber;
private string _idNumber;
private DateTime? _dateOfBirth;
private int? _age;
private string _gender;
private string _passportNumber;
private bool _isCitizen;
private bool _isSearch;
private bool _showUserControl;
private bool _showPassportFields;
private bool _hasContactNumber;
private ObservableCollection<string> _genderList;
private int? _planId;
private IList<PolicyGrid> _policies;
private Principal _mainMember;
private Lead _lead;
private Membership _membership;
private IGetSavviUow _uow;
private IIdNumberValidation _idNumberValidation;
private ICustomPrincipal _principal;
private ISalesValidation _salesValidation;
private IRegionManager _regionManager;
#endregion
#region Properties
public string Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
public int SelectedIdType
{
get { return _selectedIdType; }
set
{
SetProperty(ref _selectedIdType, value, this);
if (_selectedIdType == 2)
{
this.ShowPassportFields = true;
this.IsCitizen = false;
}
else
{
this.ShowPassportFields = false;
this.IsCitizen = true;
}
}
}
public ObservableCollection<KeyValuePair<int, string>> IdTypes
{
get
{
return new ObservableCollection<KeyValuePair<int, string>>()
{
new KeyValuePair<int, string>(1, "RSA ID Number"),
new KeyValuePair<int, string>(2, "Passport")
};
}
}
[Required]
public string ContactNumber
{
get { return _contactNumber; }
set
{
SetProperty(ref _contactNumber, value, this);
}
}
[IdValidation("SelectedIdType")]
[RequiredIf("SelectedIdType", 1)]
[Display(Name = "ID Number")]
public string IdNumber
{
get { return _idNumber; }
set
{
SetProperty(ref _idNumber, value, this);
if (_idNumberValidation.IsCitizen(_idNumber))
{
this.IsCitizen = true;
SetIdProperties();
}
}
}
[RequiredIf("SelectedIdType", 2)]
[Display(Name = "Date of Birth")]
public Nullable<DateTime> DateOfBirth
{
get { return _dateOfBirth; }
set
{
SetProperty(ref _dateOfBirth, value, this);
if (_dateOfBirth != null)
this.Age = DateTime.Today.Year - _dateOfBirth.Value.Year;
}
}
[AgeMinMax("PlanId")]
public Nullable<int> Age
{
get { return _age; }
set
{
SetProperty(ref _age, value, this);
}
}
[RequiredIf("SelectedIdType", 2)]
public string Gender
{
get { return _gender; }
set
{
SetProperty(ref _gender, value, this);
}
}
public ObservableCollection<string> GenderList
{
get { return _genderList; }
set
{
SetProperty(ref _genderList, value);
}
}
[RequiredIf("SelectedIdType", 2)]
[Display(Name = "Passport Number")]
public string PassportNumber
{
get { return _passportNumber; }
set
{
SetProperty(ref _passportNumber, value, this);
}
}
public bool IsCitizen
{
get { return _isCitizen; }
set { SetProperty(ref _isCitizen, value, this); }
}
public bool IsSearch
{
get { return _isSearch; }
set { SetProperty(ref _isSearch, value, this); }
}
public bool ShowUserControl
{
get { return _showUserControl; }
set { SetProperty(ref _showUserControl, value, this); }
}
public bool ShowPassportFields
{
get { return _showPassportFields; }
set { SetProperty(ref _showPassportFields, value, this); }
}
public bool HasContactNumber
{
get { return _hasContactNumber; }
set { SetProperty(ref _hasContactNumber, value, this); }
}
public Nullable<int> PlanId
{
get { return _planId; }
set { _planId = value; }
}
public IList<PolicyGrid> Policies
{
get { return _policies; }
set { SetProperty(ref _policies, value); }
}
#endregion
#region Methods
private void SetIdProperties()
{
this.Age = _idNumberValidation.GetAge(DateTime.Today, this.IdNumber);
this.DateOfBirth = _idNumberValidation.GetDateOfBirth(this.IdNumber);
this.Gender = _idNumberValidation.GetGender(this.IdNumber);
}
private void GetLeadInfo(int callQueueId)
{
ClearProperties();
var callQueue = _uow.RepoCallQueue.GetLeadByCallQueueIdRefId(callQueueId, _principal.CustomIdentity.RefId);
this.ShowUserControl = true;
var leadCallQueue = callQueue.Lead_CallQueue.FirstOrDefault(x => x.CallQueueId == callQueueId);
_lead = leadCallQueue.Lead;
this.Name = _lead.FirstName + " " + _lead.Surname;
this.IdNumber = _lead.IdNumber;
this.PlanId = _lead.PlanId;
if (!string.IsNullOrEmpty(_lead.Mobile))
{
this.HasContactNumber = true;
this.ContactNumber = _lead.Mobile;
}
if (!string.IsNullOrEmpty(_lead.IdNumber) &&
_idNumberValidation.IsCitizen(_lead.IdNumber))
{
this.SelectedIdType = 1;
}
else if (!string.IsNullOrEmpty(_lead.IdNumber))
{
this.SelectedIdType = 2;
}
}
private void ClearProperties()
{
this.IdNumber = string.Empty;
this.DateOfBirth = null;
this.Gender = null;
this.Age = null;
}
private void SearchedMembership(SearchArgs arg)
{
ClearProperties();
this.ShowUserControl = true;
List<Membership> memberships = new List<Membership>();
if (!string.IsNullOrEmpty(arg.SearchedId))
{
switch (arg.SearchingType)
{
case 1:
//Membership Number
memberships = _uow.RepoMembership.GetMembershipsByMembershipNumber(Convert.ToInt32(arg.SearchedId)).ToList();
break;
case 2:
//ID Number
memberships = _uow.RepoMembership.GetMembershipsByIdNumber(arg.SearchedId).ToList();
break;
case 3:
//Passport
memberships = _uow.RepoMembership.GetMembershipsByPassport(arg.SearchedId).ToList();
break;
default:
throw new ArgumentException("Uknown Searching type!");
}
_mainMember = memberships.FirstOrDefault().Principal;
if(memberships.Count > 0)
this.Policies = memberships.Select(x => new PolicyGrid(
x.Id,
_uow.Plan.GetById(x.PlanId.Value).Description,
_uow.MembershipStatus.GetById(x.MembershipStatusId).Description,
x.CommenceDate.HasValue?x.CommenceDate.Value.ToString("dd/MM/yyyy") : null,
x.ResignationDate.HasValue ? x.ResignationDate.Value.ToString("dd/MM/yyyy") : null)).ToList();
this.Name = _mainMember.FirstName + " " + _mainMember.Surname;
this.IdNumber = _mainMember.IdNumber;
this.PlanId = _uow.RepoMembership.GetLatestMembership(this.IdNumber).PlanId;
if (!string.IsNullOrEmpty(_mainMember.Mobile))
{
this.HasContactNumber = true;
this.ContactNumber = _mainMember.Mobile;
}
if (!string.IsNullOrEmpty(_mainMember.IdNumber) &&
_idNumberValidation.IsCitizen(_mainMember.IdNumber))
{
this.SelectedIdType = 1;
}
else if (!string.IsNullOrEmpty(_mainMember.IdNumber))
{
this.SelectedIdType = 2;
}
}
}
private void RaiseCommands(object value)
{
if (!string.IsNullOrEmpty(this.IdNumber))
{
if (!_salesValidation.IdNumberExists(this.IdNumber) && !this.HasErrors)
{
this.Aggregator.GetEvent<CanCreateNewMembership>().Publish(true);
}
else if (_salesValidation.IdNumberExists(this.IdNumber) &&
!_salesValidation.IncompleteApplication(this.IdNumber) &&
!_salesValidation.CanUpgrade(this.IdNumber) &&
!_salesValidation.CanReInstate(this.IdNumber))
{
//this.Aggregator.GetEvent<CanCreateNewMembership>().Publish(true);
}
else
{
this.Aggregator.GetEvent<CanCreateNewMembership>().Publish(false);
}
if (_salesValidation.IdNumberExists(this.IdNumber) &&
!this.HasErrors && _salesValidation.IncompleteApplication(this.IdNumber))
{
this.Aggregator.GetEvent<CanContinueEvent>().Publish(true);
}
else
{
this.Aggregator.GetEvent<CanContinueEvent>().Publish(false);
}
if (_salesValidation.IdNumberExists(this.IdNumber) &&
_salesValidation.CanUpgrade(this.IdNumber))
{
this.Aggregator.GetEvent<CanUpgradeEvent>().Publish(true);
}
else
{
this.Aggregator.GetEvent<CanUpgradeEvent>().Publish(false);
}
if (_salesValidation.IdNumberExists(this.IdNumber) &&
_salesValidation.CanReInstate(this.IdNumber))
{
this.Aggregator.GetEvent<CanReinstateEvent>().Publish(true);
}
else
{
this.Aggregator.GetEvent<CanReinstateEvent>().Publish(false);
}
if (this.HasErrors)
{
this.Aggregator.GetEvent<CanCreateNewMembership>().Publish(false);
this.Aggregator.GetEvent<CanContinueEvent>().Publish(false);
this.Aggregator.GetEvent<CanUpgradeEvent>().Publish(false);
this.Aggregator.GetEvent<CanReinstateEvent>().Publish(false);
}
}
}
private void Continue(string view)
{
if (view == ModuleViewConstants.PlanSelectionView)
this.Aggregator.GetEvent<ShowViewEvent>().Publish(
ModuleViewConstants.PlanSelectionView);
}
private void EventSubscriptions()
{
this.Aggregator.GetEvent<LoadLeadInfoEvent>().Subscribe(GetLeadInfo);
this.Aggregator.GetEvent<RaiseCommandAndEventsEvent>().Subscribe(RaiseCommands);
this.Aggregator.GetEvent<SearchEvent>().Subscribe(SearchedMembership);
this.Aggregator.GetEvent<ContinueEvent>().Subscribe(Continue);
this.Aggregator.GetEvent<SaveEvent>().Subscribe(SaveProgress);
}
bool INavigationAware.IsNavigationTarget(NavigationContext navigationContext)
{
_membership = GetMembership(navigationContext);
return _membership == null;
}
private Membership GetMembership(NavigationContext navigationContext)
{
if (navigationContext.NavigationService.Region.Context != null &&
navigationContext.NavigationService.Region.Context is Membership)
return (Membership)navigationContext.NavigationService.Region.Context;
return null;
}
void INavigationAware.OnNavigatedFrom(NavigationContext navigationContext)
{
var refId = (Thread.CurrentPrincipal as ICustomPrincipal).CustomIdentity.RefId;
this.SaveProgress(refId);
if (_membership != null)
{
navigationContext.NavigationService.Region.Context = _membership;
}
}
void INavigationAware.OnNavigatedTo(NavigationContext navigationContext)
{
}
private void SaveProgress(Guid refId)
{
var agentId = _uow.User.GetByRef(refId).Id;
_mainMember = new Principal();
if (_lead != null)
Mapper.Map(_lead, _mainMember);
if (_membership == null)
_membership = new Membership(
Guid.NewGuid(),
_lead.PlanId.HasValue?_lead.PlanId : null,
null,
null,
null,
DateTime.Now,
agentId,
_mainMember.Id,
(int)BillingStatusEnum.BAFP,
(int)MembershipStatusEnum.PWS,
null,
null,
null);
if (_mainMember != null)
{
//To Take out when Db is working
var principalId = _uow.Principal.GetAll().Max(x => x.Id);
_mainMember.Id = principalId + 1;
_membership.Principal = _mainMember;
}
//To Take out when Db is working
var id = _uow.Membership.GetAll().Max(x => x.Id);
_membership.Id = id + 1;
//===================================================\\
}
#endregion
#region Commands
#endregion
#region EventHandlers
#endregion
#region Constructors
public PreQualificationViewModel(
IEventAggregator aggregator,
IUnityContainer container,
IRegionManager regionManager,
IGetSavviUow uow,
IIdNumberValidation idNumberValidation,
ISalesValidation salesValidation) :
base(aggregator, container)
{
_uow = uow;
_regionManager = regionManager;
_principal = Thread.CurrentPrincipal as ICustomPrincipal;
_idNumberValidation = idNumberValidation;
_salesValidation = salesValidation;
EventSubscriptions();
this.GenderList = new ObservableCollection<string>()
{
"Male",
"Female"
};
}
#endregion
}
Please Help!!!
i defined bellow classes for my EF in wpf for use in mvvm pattern:
public class ProductGroup : ViewModelBase
{
public long ID { get; set; }
private string _Title;
public string Title
{
get { return _Title; }
set
{
if (_Title != value)
{
_Title = value;
this.RaisePropertyChanged("Title");
}
}
}
private byte[] _Icon;
public byte[] Icon
{
get { return _Icon; }
set
{
if (_Icon != value)
{
_Icon = value;
this.RaisePropertyChanged("Icon");
}
}
}
private ProductGroup _Parent;
public ProductGroup Parent
{
get { return _Parent; }
set
{
if (_Parent != value)
{
_Parent = value;
this.RaisePropertyChanged("Parent");
}
}
}
private ObservableCollection<ProductGroup> _Childs;
public ObservableCollection<ProductGroup> Childs
{
get { return _Childs; }
set
{
if (_Childs != value)
{
_Childs = value;
this.RaisePropertyChanged("Childs");
}
}
}
private ObservableCollection<Product> _Products;
public ObservableCollection<Product> Products
{
get { return _Products; }
set
{
if (_Products != value)
{
_Products = value;
this.RaisePropertyChanged("Products");
}
}
}
}
public class Product : ViewModelBase
{
public long ID { get; set; }
private ProductGroup _Gorup;
public ProductGroup Gorup
{
get { return _Gorup; }
set
{
if (_Gorup != value)
{
_Gorup = value;
this.RaisePropertyChanged("Gorup");
}
}
}
private string _Name;
public string Name
{
get { return _Name; }
set
{
if (_Name != value)
{
_Name = value;
this.RaisePropertyChanged("Name");
}
}
}
}
is my definitions correct ??
when i want to remove an item from ProductGroups ,The following error occurs:
An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.
Note:
The target ProductGroup is a child of another ProductGroup
the target ProductGroup has no Child and Product
I have a Silverlight application that I am currently working that implements Caliburn.Micro for its MVVM framework. Things are working fine but I am noticing some funniness in some of the binding. What I have is a ShellViewModel and a ShellView that handle the navigation for the application. The ShellViewModel has a list of the loaded ViewModels for the application. The ShellViewModel inherits from Conductor so that it can handle all the activation and deactivation.
I also have a type of ViewModel base class called BaseConductorViewModel that also inherits from Conductor. This is for ViewModel’s that are basically Master-Detail views. For these BaseConductorViewModels I have a BindableCollection called Items. The idea being to bind this collection to a ListBox or other ItemsControl.
When I create an child of this ViewModel and an associated View I have noticed that the ListBox(in this case) only refreshes the binding when I change the ActiveItem at the ShellViewModel level. So when the application initially loads and this view is the default active view you won’t see anything in the list (I am calling Ria service to get the data for this list). But, if I click on another ViewModel on the ShellViewModel/ShellView and then click back it will show the items in the list. This also follows for adding items to the list or removing them. It won’t refresh unless I switch active views. This seems very odd to me and I can’t seem to figure out a way to get it bind as I would except. One more thing to note, when I am adding/removing items; I call the Refresh method, currently I am not using the NotifyOfPropertyChange method though I did try that previously to the same result.
Does anyone have any ideas of what might be going on here? Or any ideas on how I could go about trying to debug this?
Thank you in advance!
Here is the ShellViewModel
public abstract class ShellViewModel<V,M>:Conductor<IViewModel<V, M>>.Collection.OneActive, IViewModelCatalogShell<V,M>
where V:IView
where M:IModel
{
#region Properties/Members
public ViewModelSelectedItemList<V, M> Catalog { get; set; }
#endregion
#region Constructors
public ShellViewModel()
{
Catalog = new ViewModelSelectedItemList<V, M>();
}
#endregion
}
And here is the BaseConductorViewModel
public abstract class BaseConductorViewModel<T,V,M>:Conductor<T>, IViewModel<V, M>
where V:IView
where M:IModel
{
#region Properties/Members
protected Guid _id=Guid.Empty;
public Guid Id
{
get{return _id;}
set
{
_id =value;
NotifyOfPropertyChange("Id");
}
}
protected string _name=string.Empty;
public string Name
{
get { return _name; }
set
{
_name = value;
NotifyOfPropertyChange("Name");
}
}
public string TypeName
{
get
{
return this.GetType().FullName;
}
}
protected string _description = string.Empty;
public string Description
{
get { return _description; }
protected set
{
_description = value;
NotifyOfPropertyChange(() => Description);
}
}
protected V _view;
public V View
{
get { return _view; }
set
{
_view = value;
NotifyOfPropertyChange("View");
}
}
protected M _model;
public M Model
{
get { return _model; }
set
{
_model = value;
NotifyOfPropertyChange("Model");
}
}
protected SelectedItemList<T> _items;
public SelectedItemList<T> Items
{
get { return _items; }
set
{
_items = value;
NotifyOfPropertyChange(() => Items);
}
}
protected Guid _lastModifiedBy = Guid.Empty;
public Guid LastModifiedBy
{
get { return _lastModifiedBy; }
set
{
_lastModifiedBy = value;
NotifyOfPropertyChange("LastModifiedBy");
}
}
protected DateTime _lastModifiedOn = DateTime.Today;
public DateTime LastModifiedOn
{
get { return _lastModifiedOn; }
set
{
_lastModifiedOn = value;
NotifyOfPropertyChange("LastModifiedOn");
}
}
protected string _imageSource = string.Empty;
public string ImageSource
{
get { return _imageSource; }
protected set
{
_imageSource = value;
NotifyOfPropertyChange("ImageSource");
}
}
#endregion
#region Constructors
public BaseConductorViewModel()
{
_items = new SelectedItemList<T>();
Items.SelectItemChanged += new SelectedItemChangedEvent(Items_SelectItemChanged);
Items.SelectedIndexChanged += new SelectedIndexChangedEvent(Items_SelectedIndexChanged);
LoadData();
}
public BaseConductorViewModel(V view, M model)
:this()
{
_items = new SelectedItemList<T>();
View = view;
Model = model;
Items.SelectItemChanged += new SelectedItemChangedEvent(Items_SelectItemChanged);
Items.SelectedIndexChanged += new SelectedIndexChangedEvent(Items_SelectedIndexChanged);
LoadData();
}
#endregion
#region Methods
public abstract void LoadData();
#endregion
#region Event Handlers
private void Items_SelectItemChanged()
{
ChangeActiveItem(Items.SelectedItem, true);
OnActiveItemChanged();
}
private void Items_SelectedIndexChanged(int index)
{
ChangeActiveItem(Items.SelectedItem, true);
OnActiveItemChanged();
}
#endregion
}
The ViewModelSelectedItemList is just a typed version of this class
public class SelectedItemList<T>:IObservableCollection<T>
{
#region Properties/Members
protected BindableCollection<T> _items = new BindableCollection<T>();
protected bool _isReadOnly = false;
protected bool _isNotifying = true;
public bool IsNotifying
{
get
{
return _isNotifying;
}
set
{
_isNotifying = value;
}
}
public int Count
{
get { return _items.Count; }
}
protected int _selectedIndex = -1;
public int SelectedIndex
{
get { return _selectedIndex; }
set
{
_selectedIndex = value;
NotifyOfPropertyChange("SelectedIndex");
FireSelectedIndexChangedEvent(_selectedIndex);
}
}
public T SelectedItem
{
get
{ return _items[_selectedIndex]; }
set
{
_selectedIndex = _items.IndexOf(value);
NotifyOfPropertyChange("SelectedItem");
FireSelectedItemChangedEvent();
}
}
#endregion
#region Events
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
public event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanged;
public event SelectedIndexChangedEvent SelectedIndexChanged;
public event SelectedItemChangedEvent SelectItemChanged;
#endregion
#region Constructors
#endregion
#region Methods
public void AddRange(System.Collections.Generic.IEnumerable<T> items)
{
if (!_isReadOnly)
{
foreach (T item in items)
{
_items.Add(item);
}
if (_isNotifying)
{
NotifyOfPropertyChange("Count");
}
}
}
public void RemoveRange(System.Collections.Generic.IEnumerable<T> items)
{
if (!_isReadOnly)
{
foreach (T item in items)
{
_items.Remove(item);
}
if (_isNotifying)
{
NotifyOfPropertyChange("Count");
}
}
}
public int IndexOf(T item)
{
return _items.IndexOf(item);
}
public void Insert(int index, T item)
{
if (!_isReadOnly)
{
_items.Insert(index, item);
if (_isNotifying)
{
NotifyOfPropertyChange("Count");
}
}
}
public void RemoveAt(int index)
{
if (!_isReadOnly)
{
_items.RemoveAt(index);
if (_isNotifying)
{
NotifyOfPropertyChange("Count");
}
}
}
public T this[int index]
{
get
{
return _items[index];
}
set
{
_items[index] = value;
}
}
public void Add(T item)
{
if (!_isReadOnly)
{
_items.Add(item);
if (_isNotifying)
{
NotifyOfPropertyChange("Count");
_items.Refresh();
}
if (_items.Count == 1)
{
SelectedIndex = 0;
}
}
}
public bool Remove(T item)
{
if (!_isReadOnly)
{
if (_isNotifying)
{
NotifyOfPropertyChange("Count");
}
return _items.Remove(item);
}
else
{
return false;
}
}
public void Clear()
{
_items.Clear();
}
public bool Contains(T item)
{
return _items.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
if (!_isReadOnly)
{
_items.CopyTo(array, arrayIndex);
if (_isNotifying)
{
NotifyOfPropertyChange("Count");
}
}
}
public bool IsReadOnly
{
get { return _isReadOnly; }
}
public void Lock()
{
_isReadOnly = true;
}
public void Unlock()
{
_isReadOnly = false;
}
public System.Collections.Generic.IEnumerator<T> GetEnumerator()
{
return _items.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _items.GetEnumerator();
}
public void NotifyOfPropertyChange(string propertyName)
{
FirePropertyChangedEvent(propertyName);
}
public void Refresh()
{
_items.Refresh();
}
#region Helper Methods
protected void FirePropertyChangedEvent(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
protected void FireCollectionChangedEvent(NotifyCollectionChangedAction action)
{
if (CollectionChanged != null)
{
CollectionChanged(this, new System.Collections.Specialized.NotifyCollectionChangedEventArgs(action));
}
}
protected void FireSelectedIndexChangedEvent(int index)
{
if (SelectedIndexChanged != null)
{
SelectedIndexChanged(index);
}
}
protected void FireSelectedItemChangedEvent()
{
if (SelectItemChanged != null)
{
SelectItemChanged();
}
}
#endregion
#endregion
}
Not sure if you're problem has something to do with this, from the docs:
Since all OOTB implementations of IConductor inherit from Screen it
means that they too have a lifecycle and that lifecycle cascades to
whatever items they are conducting. So, if a conductor is deactivated,
it’s ActiveItem will be deactivated as well. If you try to close a
conductor, it’s going to only be able to close if all of the items it
conducts can close. This turns out to be a very powerful feature.
There’s one aspect about this that I’ve noticed frequently trips up
developers. If you activate an item in a conductor that is itself not
active, that item won’t actually be activated until the conductor gets
activated. This makes sense when you think about it, but can
occasionally cause hair pulling.
edit:
I think I see what you're trying to do, a couple questions though:
Your ShellViewModel is
Conductor<IViewModel<V,M>>.Collection.OneActive, when is Catalog
activated? I'd think you'd want to add Catalog to Items, then
Activate it.
With the BaseConductorViewModel, it inherits from Conductor which
inherits from Screen, which gets a reference to it's view when it's
bound. I'm not sure what the View property you add is for.
CM can handle setting the selected item for you. So for a master
detail situation where you have an ItemsControl, CM will set the
SelectedItem and from that you can populate the detail.
I'm starting Caliburn Micro development and I have thought of an architecture where a viewmodel has properties, injected by MEF, which are other viewmodels. That way I can use contentcontrols in the view to position them the way I want.
public class ContactsProfileViewModel : Conductor<IContentItem>, IContactsModuleViewModel, IModule, IPartImportsSatisfiedNotification
{
private string name;
private string nameCaption;
private ISingleLineTextContentItem firstName;
private ISingleLineTextContentItem lastName;
public ContactsProfileViewModel()
{
this.DisplayName = "Contact Tab";
}
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
this.NotifyOfPropertyChange(() => Name);
}
}
public string NameCaption
{
get
{
return this.nameCaption;
}
set
{
this.nameCaption = value;
this.NotifyOfPropertyChange(() => NameCaption);
}
}
[Import(typeof(ISingleLineTextContentItem))]
public ISingleLineTextContentItem FirstName
{
get { return this.firstName; }
set
{
this.firstName = value;
this.NotifyOfPropertyChange(() => FirstName);
}
}
[Import(typeof(ISingleLineTextContentItem))]
public ISingleLineTextContentItem LastName
{
get { return this.lastName; }
set
{
this.lastName = value;
this.NotifyOfPropertyChange(() => LastName);
}
}
The viewmodel of SingleLineTextContentItem looks like this:
[Export(typeof(ISingleLineTextContentItem))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class SingleLineTextContentItemViewModel : PropertyChangedBase, ISingleLineTextContentItem
{
private string textBoxText;
private string caption;
public string TextBoxText
{
get { return textBoxText; }
set
{
textBoxText = value;
this.NotifyOfPropertyChange(() => TextBoxText);
}
}
public string Caption
{
get { return caption; }
set
{
this.caption = value;
this.NotifyOfPropertyChange(() => Caption);
}
}
}
Now, I need a way to bind the NameCaption property to the Caption property in a two-way manner. Is that possible? I'm I on the right track with this or is there a better way to do this?
Thanks,
Roland
What I do is instead of having a backing field just route to the other view model
public string NameCaption
{
get
{
return FirstName.Caption;
}
set
{
FirstName.Caption = value;
this.NotifyOfPropertyChange(() => NameCaption);
}
}
However if the Caption property on the ISingleLineTextContentItem can get set independently then you need to register changes on the event and have the view model listen to changes. So instead you need somthing along the lines of:
public string NameCaption
{
get
{
return FirstName == null ? string.Empty : FirstName.Caption;
}
set
{
if(FirstName != null)
FirstName.Caption = value;
}
}
[Import(typeof(ISingleLineTextContentItem))]
public ISingleLineTextContentItem FirstName
{
get { return this.firstName; }
set
{
if(this.FirstName != null)
this.FirstName.PropertyChanged -= FirstNameChanged;
this.firstName = value;
if(this.FirstName != null)
this.FirstName.PropertyChanged += FirstNameChanged;
this.NotifyOfPropertyChange(() => FirstName);
this.NotifyOfPropertyChange(() => NameCaption);
}
}
private void FirstNameChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertName == "Caption")
this.NotifyOfPropertyChange(() => NameCaption);
}
Since either the Caption property or the FirstName property can change then we need to raise the event in the FirstName property and in the handler.