/// <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 = MvxCloseViewCommand.GetHolder(parameter); if (holder == null) { return(true); } return(!MvxContainer.GetHasClosingAction(holder)); } catch (Exception) { } return(true); }
/// <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.IoCProvider.Resolve <IMvxNavigationService>(); foreach (var mv in history.Select((c) => MvxWpfPresenter.GetViewModel(c)).ToList()) { await nav.Close(mv); } MvxContainer.SetHasClosingAction(holder, false); RaiseCanExecuteChanged(); } }
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 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.IoCProvider.Resolve <MvvmCross.Navigation.IMvxNavigationService>(); nav.Close(vm as MvvmCross.ViewModels.IMvxViewModel); MvxContainer.SetHasClosingAction(holder, false); RaiseCanExecuteChanged(); }