/// <summary> /// Returns true if parameter has a value that can lead to a holder. /// </summary> /// <param name="parameter"> /// Could be a container id (<c>string</c>), container (<see cref="ItemsControl"/>), or holder (<see cref="ContentControl"/>). /// </param> /// <returns></returns> public bool CanExecute(object parameter) { try { var holder = GetHolder(parameter); if (holder == null) { return(true); } return(!MvxContainer.GetHasClosingAction(holder)); } catch (Exception) { } return(true); }
internal static ContentControl GetHolder(object parameter) { var container = parameter as ItemsControl; ContentControl holder = null; if (container == null && parameter is string id) { container = MvxContainer.GetContainerById(id); } if (container != null && container.Items.Count > 0) { if (container is Selector selector) { holder = selector.SelectedItem as ContentControl; } holder = container.Items[container.Items.Count - 1] as ContentControl; } if (holder == null) { holder = parameter as ContentControl; } return(holder); }
/// <summary> /// Execute a close command on a holder. /// </summary> /// <param name="parameter"> /// Could be a container id (<c>string</c>), container (<see cref="ItemsControl"/>), or holder (<see cref="ContentControl"/>). /// </param> /// <remarks> /// If the parameter is <see cref="string"/>, the command will search for the container of same id /// and if the parameter is <see cref="ItemsControl"/> it will use it as a container. /// In both cases the command will get the selected holder in the container (if it is a <see cref="Selector"/>) /// or it will use the last holder in the items collection. /// The close command is will close all the views in the holder navigation stack. /// </remarks> public async void Execute(object parameter) { var holder = MvxCloseViewCommand.GetHolder(parameter); if (holder == null) { throw new InvalidCastException("Command parameter should be a content control."); } var history = MvxContainer.GetHolderHistory(holder); if (history != null) { MvxContainer.SetHasClosingAction(holder, true); RaiseCanExecuteChanged(); var nav = Mvx.Resolve <IMvxNavigationService>(); foreach (var mv in history.Select((c) => MvxWpfPresenter.GetViewModel(c)).ToList()) { await nav.Close(mv); } MvxContainer.SetHasClosingAction(holder, false); RaiseCanExecuteChanged(); } }
/// <summary> /// Execute a back command on a holder. /// </summary> /// <param name="parameter"> /// Could be a container id (<c>string</c>), container (<see cref="ItemsControl"/>), or holder (<see cref="ContentControl"/>). /// </param> /// <remarks> /// If the parameter is <see cref="string"/>, the command will search for the container of same id /// and if the parameter is <see cref="ItemsControl"/> it will use it as a container. /// In both cases the command will get the selected holder in the container (if it is a <see cref="Selector"/>) /// or it will use the last holder in the items collection. /// The back command is actually a close command for the last view in the holder. /// </remarks> public void Execute(object parameter) { var holder = GetHolder(parameter); if (holder == null) { return; } var view = holder.Content as FrameworkElement; if (view == null) { return; } object vm = null; if (view is MvvmCross.Views.IMvxView mvxv) { vm = mvxv.ViewModel; } if (vm == null) { vm = view.DataContext; } if (vm == null) { return; } MvxContainer.SetHasClosingAction(holder, true); RaiseCanExecuteChanged(); var nav = Mvx.Resolve <Navigation.IMvxNavigationService>(); nav.Close(vm as ViewModels.IMvxViewModel); MvxContainer.SetHasClosingAction(holder, false); RaiseCanExecuteChanged(); }