I'm using a NavigationController to display my View that inherit from MvxViewController. My NavigationController is hidden.
If I try to use back with gesture on iOS 7 as
public override void ViewDidLoad()
{
...
this.NavigationController.InteractivePopGestureRecognizer.Enabled = true;
...
}
i have a NullPointer exception on InteractivePopGestureRecognizer
Object reference not set to an instance of an object
how could i simulate back without show navigation controller?
Related
I have a TabbedPage, which includes 3 pages (A,B,C). I need to detect (using some override method) when a page is active/selected from tabbed control. I tried some override methods such us OnAppearing with no result, because during debugging process I noticed OnAppearing was fired when TabbedPage was firstly initialized, so when I selected for example the second page (page B) this method was not fired. Is there any optimal way to detect switching between tabs inside child view?
Just like
ToolmakerSteve sayed, the tabbedpage has the CurrentPageChanged event, so you can override the OnCurrentPageChanged() method of the TabbedPage. Such as:
public partial class TabbedPage1 : TabbedPage
{
public TabbedPage1()
{
InitializeComponent();
}
protected override void OnCurrentPageChanged()
{
if(CurrentPage == Children[0])//Children[0] is the page A
{
....
}else if(CurrentPage == Children[1])//Children[1] is the page B
{
.....
}
else
{
......
}
base.OnCurrentPageChanged();
}
}
I have an application with a Loginscreen, and a Mainpage
When I initialize my application I set the Navigation to "NavigationPage/LoginPage". When I log into the application I reset the stack with absolute navigation using the route "/NavigationPage/MainPage". All of my pages have a label bound to the current navigation Uri and when I reset the stack after logging in and navigate to the mainpage my Uri looks like this
/NavigationPage/LoginPage/MainPage?useModalNavigation=true
I've read that if you have duplicate pages on top of one another this can cause the navigation to become modal by default. But I'm resetting the stack and even resetting the NavigationPage. This doesn't cause any immediate issues, but I have found that in deeper parts of my application's navigation stack, some navigation isn't working and this seems to be the cause
Does anyone know why this is happening?
My code
App.xaml.cs
protected override async void OnInitialized()
{
InitializeComponent();
await NavigationService.NavigateAsync("NavigationPage/LoginPage");
}
LoginPageViewModel.cs
public ICommand LoginCommand { get; }
public LoginPageViewModel(INavigationService navigationService) : base(navigationService)
{
LoginCommand = new Command(Login);
NavUri = NavigationService.GetNavigationUriPath();
}
private async void Login()
{
await NavigationService.NavigateAsync("/NavigationPage/MainPage");
}
MainPageViewModel.cs
public MainPageViewModel(INavigationService navigationService) : base(navigationService)
{
Title = "Main Page";
NavUri = NavigationService.GetNavigationUriPath(); // current URI on the mainpage is /NavigationPage/LoginPage/MainPage?useModalNavigation=true
NavigateToPageACommand = new Command(NavigateToPageA);
}
I'm using;
Xamarin Forms 4.6.0.726
Prism.Dryloc 7.2.0.1422
Appears to be just a temporary value that occurs during OnNavigatingFrom. While the stack is being reset the Navigation appears to be Modal, however it is actually not. Discovered this by adding INavigationAware to my ViewModelBase and viewing the result of GetNavigationUriPath in the OnNavigatedTo and OnNavigatingFrom Methods.
In Xamarin for mac, I decided to make multiple views to be used within my main view using the MVVM pattern.
The thing is that I have a ListView within my MainPage which pulls a List of items from a model, and the list is populated within a child view, with its own ViewModel.
When I add a new service from the child view, I would like for the OnPropertyChanged event on the parent view model to trigger.
It is working by navigating to the parent view and setting the animation to false, but this is not really nice looking. It worked though when I had all code within one ViewModel.
How I tried to achieve this, and the errors I got:
0 - Accessing the command within the child model from the parent model, and passing the propertychanged event handler along.
I Couldn't do it. I tried this by making a bindable command like below, but this is not doable for me as I don't think it is possible for the command to know when the property will be changed, which is the whole point of this problem.
If it is doable, I don't know how.
//public static readonly BindableProperty SaveServiceClickedCommandProperty =
// BindableProperty.Create(
// "SaveServiceClicked",
// typeof(Command),
// typeof(NewServiceViewModel),
// null);
1 - Passing the parent view model on the child view model, and put a OnPropertyChanged(nameof(parentModel.List)) at the clicked event handler.
public class ChildViewModel : INotifyPropertyChanged
{
public ICommand AddEntryClickedCommand { get; private set; }
private MainModel mainModel;
// property changed handler
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public NewServiceViewModel()
{
Navigation = MainPage;
//async void execute() => await OpenPage();
//OpenPageCommand = new Command(execute, () => !IsBusy);
//async Task OpenPage()
//{
// await Navigation.PushAsync(new MainPage());
//}
// Here I tried to access the data from within the main model.
mainModel = new MainModel(Navigation);
InitMainModel();
void InitMainModel()
{
MainPage mainView = new MainPage();
mainView.BindingContext = mainModel;
}
async void c1() => await AddEntryClicked();
AddEntryClickedCommand = new Command(c1);
}
public async Task<bool> AddEntryClicked()
{
OnPropertyChanged(nameof(mainModel.List))
}
The attempt above created some errors as the object is already populated.
Leading to me thinking that I don't have the right approach altogether.
My solution being to re-introduce the child view within the parent view, and change IsVisible according to the button being clicked or not, as I already did with other smaller component.
I have thought about pulling the list from the child view, but that's raises the same issue of non-null collection.
Of course, the code has been modified to show only the gist.
Thanks in advance.
I have a MyView.xaml.cs and MyView.xaml which is a ContentView. It has an Entry field.
How do I focus on that Entry field each time MyView is shown on screen?
I think you can use Focus method on your PAGE when your View will be appearing like :
protected override void OnAppearing()
{
base.OnAppearing();
Entry entry = this.FindByName<Entry>("YourEntryName");
entry.Focus();
}
I have two VM - View (inherited from Screen) and Edit (inherited from Screen). View is used to display grid with data and Edit - add/edit new items into grid.
In my ShellViewModel I have the following code to activate View.
public void WorkstationView()
{
this.ActivateItem(ServiceLocator.Current.GetInstance<WorkstationViewModel>());
}
In WorkstationViewModel when user clicks on the Create button the following code is invoked
public void CreateAction()
{
EditableObject = new WorkstationDto();
TryClose(true);
}
And there is a listener to Deactivated event property, see code below (InitViewModels is invoked in ShellViewModel constructor).
private void InitViewModels()
{
#region Init
WorkstationViewModel = ServiceLocator.Current.GetInstance<WorkstationViewModel>();
WorkstationEditViewModel = ServiceLocator.Current.GetInstance<WorkstationEditViewModel>();
#endregion
#region Logic
WorkstationViewModel.Deactivated += (o, args) =>
{
if (WorkstationViewModel.EditableObject == null)
{
return;
}
WorkstationEditViewModel.EditableObject = WorkstationViewModel.EditableObject;
ActivateItem(WorkstationEditViewModel);
};
#endregion
}
The problem here is a StackOverflow exception when I close Edit view (see create action).
“Since the Conductor does not maintain a “screen collection,” the activation of each new item causes both the deactivation and close of the previously active item.” Caliburn.Micro documentation
If you are using Conductor<T>, then ActivateItem(WorkstationEditViewModel); inside of the Deactivated handler is implicitly re-triggering the deactivation of the previous viewmodel - giving you an infinite loop. Try changing your conductor to inherit from Conductor<IScreen>.Collection.OneActive instead. However, you will still have two deactivations: the one from the original TryClose operation, and a second one when you activate the new screen. Overriding DetermineNextItemToActivate can help you avoid that.