/// <summary> /// Called when the <see cref="TargetView"/> has just been unloaded. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> /// <remarks> /// This method will call the <see cref="OnTargetViewUnloadedAsync"/> which can be overriden for custom /// behavior. This method is required to protect from duplicate unloaded events. /// </remarks> #pragma warning disable AvoidAsyncVoid // Avoid async void private async void OnTargetViewUnloadedInternal(object sender, EventArgs e) #pragma warning restore AvoidAsyncVoid // Avoid async void { if (!CanUnload) { return; } Log.Debug($"Target view '{TargetViewType?.Name}' has been unloaded"); var view = TargetView; if (view != null) { _viewManager.UnregisterView(view); } IsTargetViewLoaded = false; _isFirstValidationAfterLoaded = true; await OnTargetViewUnloadedAsync(sender, e); var targetViewAsViewModelContainer = TargetView as IViewModelContainer; if (targetViewAsViewModelContainer != null) { ViewToViewModelMappingHelper.UninitializeViewToViewModelMappings(targetViewAsViewModelContainer); } IsUnloading = false; }
/// <summary> /// Called when the <see cref="TargetView"/> has just been unloaded. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> /// <remarks> /// This method will call the <see cref="OnTargetViewUnloaded"/> which can be overriden for custom /// behavior. This method is required to protect from duplicate unloaded events. /// </remarks> private void OnTargetViewUnloadedInternal(object sender, EventArgs e) { if (!CanUnload) { return; } Log.Debug("Target control '{0}' is unloaded", TargetView.GetType().Name); var view = TargetView; if (view != null) { _viewManager.UnregisterView(view); } IsTargetViewLoaded = false; _isFirstValidationAfterLoaded = true; OnTargetViewUnloaded(sender, e); var targetViewAsViewModelContainer = TargetView as IViewModelContainer; if (targetViewAsViewModelContainer != null) { ViewToViewModelMappingHelper.UninitializeViewToViewModelMappings(targetViewAsViewModelContainer); } IsUnloading = false; }
/// <summary> /// Called when the <see cref="TargetControl"/> has just been unloaded. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> /// <remarks> /// This method will call the <see cref="OnTargetControlUnloaded"/> which can be overriden for custom /// behavior. This method is required to protect from duplicate unloaded events. /// </remarks> private void OnTargetControlUnloadedInternal(object sender, UIEventArgs e) { // Don't do this again (another bug in WPF: OnLoaded is called more than OnUnloaded) if (!IsTargetControlLoaded) { return; } InvokeViewLoadEvent(ViewLoadStateEvent.Unloading); IsUnloading = true; //#if !NET // _isFirstLayoutUpdatedAfterUnloadedEvent = true; //#endif Log.Debug("Target control '{0}' is unloaded", TargetControl.GetType().Name); var view = TargetControl as IView; if (view == null) { Log.Warning("Cannot unregister view '{0}' in the view manager because it does not implement IView", TargetControl.GetType().FullName); } else { _viewManager.UnregisterView(view); } IsTargetControlLoaded = false; _isFirstValidationAfterLoaded = true; OnTargetControlUnloaded(sender, e); var targetControlAsIViewModelContainer = TargetControl as IViewModelContainer; if (targetControlAsIViewModelContainer != null) { ViewToViewModelMappingHelper.UninitializeViewToViewModelMappings(targetControlAsIViewModelContainer); } IsUnloading = false; InvokeViewLoadEvent(ViewLoadStateEvent.Unloaded); }
/// <summary> /// Called when the <see cref="TargetView"/> has just been loaded. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> /// <remarks> /// This method will call the <see cref="OnTargetViewLoadedAsync"/> which can be overriden for custom /// behavior. This method is required to protect from duplicate loaded events. /// </remarks> #pragma warning disable AvoidAsyncVoid // Avoid async void private async void OnTargetViewLoadedInternal(object sender, EventArgs e) #pragma warning restore AvoidAsyncVoid // Avoid async void { if (!CanLoad) { return; } Log.Debug($"Target view '{TargetViewType?.Name}' has been loaded"); var view = TargetView; if (view != null) { _viewManager.RegisterView(view); } IsTargetViewLoaded = true; var dataContext = view.DataContext; LastKnownDataContext = (dataContext != null) ? new WeakReference(dataContext) : null; await OnTargetViewLoadedAsync(sender, e); TargetView.EnsureVisualTree(); var targetViewAsViewModelContainer = TargetView as IViewModelContainer; if (targetViewAsViewModelContainer != null) { ViewToViewModelMappingHelper.InitializeViewToViewModelMappings(targetViewAsViewModelContainer); } TargetView.Dispatch(() => { #pragma warning disable 4014 // No need to await InitializeViewModelAsync(); #pragma warning restore 4014 }); IsLoading = false; }
/// <summary> /// Called when the <see cref="TargetView"/> has just been loaded. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> /// <remarks> /// This method will call the <see cref="OnTargetViewLoaded"/> which can be overriden for custom /// behavior. This method is required to protect from duplicate loaded events. /// </remarks> private void OnTargetViewLoadedInternal(object sender, EventArgs e) { if (!CanLoad) { return; } Log.Debug("Target view '{0}' is loaded", TargetView.GetType().Name); var view = TargetView; if (view != null) { _viewManager.RegisterView(view); } IsTargetViewLoaded = true; OnTargetViewLoaded(sender, e); TargetView.EnsureVisualTree(); var targetViewAsViewModelContainer = TargetView as IViewModelContainer; if (targetViewAsViewModelContainer != null) { ViewToViewModelMappingHelper.InitializeViewToViewModelMappings(targetViewAsViewModelContainer); } TargetView.Dispatch(() => { #pragma warning disable 4014 // No need to await InitializeViewModelAsync(); #pragma warning restore 4014 }); IsLoading = false; }
/// <summary> /// Called when the <see cref="TargetControl"/> has just been loaded. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> /// <remarks> /// This method will call the <see cref="OnTargetControlLoaded"/> which can be overriden for custom /// behavior. This method is required to protect from duplicate loaded events. /// </remarks> private void OnTargetControlLoadedInternal(object sender, UIEventArgs e) { // Don't do this again (another bug in WPF: OnLoaded is called more than OnUnloaded) if (IsTargetControlLoaded) { return; } if (!CanControlBeLoaded) { Log.Debug("Received Loaded or LayoutUpdated, but CanControlBeLoaded is false thus not treating the control as loaded"); return; } Log.Debug("Target control '{0}' is loaded", TargetControl.GetType().Name); InvokeViewLoadEvent(ViewLoadStateEvent.Loading); IsLoading = true; var view = TargetControl as IView; if (view == null) { Log.Warning("Cannot register view '{0}' in the view manager because it does not implement IView", TargetControl.GetType().FullName); } else { _viewManager.RegisterView(view); } IsTargetControlLoaded = true; OnTargetControlLoaded(sender, e); #if !NET // According to the documentation, no visual tree is garantueed in the Loaded event of the user control. // However, as a solution the documentation says you need to manually call ApplyTemplate, so let's do that. // For more info, see http://msdn.microsoft.com/en-us/library/ms596558(vs.95) var targetControl = TargetControl as Control; if (targetControl != null) { (targetControl).ApplyTemplate(); } #endif var targetControlAsIViewModelContainer = TargetControl as IViewModelContainer; if (targetControlAsIViewModelContainer != null) { ViewToViewModelMappingHelper.InitializeViewToViewModelMappings(targetControlAsIViewModelContainer); } var dispatcher = TargetControl.Dispatcher; dispatcher.BeginInvokeIfRequired(() => { if (ViewModel != null) { // Initialize the view model. The view model itself is responsible to prevent double initialization ViewModel.InitializeViewModel(); // Revalidate since the control already initialized the view model before the control // was visible, therefore the WPF engine does not show warnings and errors var viewModelAsViewModelBase = ViewModel as ViewModelBase; if (viewModelAsViewModelBase != null) { viewModelAsViewModelBase.Validate(true, false); } else { ViewModel.ValidateViewModel(true, false); } _isFirstValidationAfterLoaded = true; } }); IsLoading = false; InvokeViewLoadEvent(ViewLoadStateEvent.Loaded); }