trying to trigger even when navigating from Usercontrol windows phone 8 - c#

Yesterday I was refactoring some code in my windows phone project to try and use mvvm. I added binding to the toggleswitched on the page etc. the previous code also had evenhandlers for each toggleswitches checked and unchecked events. anyway I managed to clean it up. But my problem occured when I was trying to get code in my viewmodel to execute when i navigated away from this page. Initially I tried this
protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
{
viewmodel.SaveSettings();
}
after a bit of time debugging. I found this method wasnt being called. This was due to the fact that I was calling it in the code behind of a UserControl. Ive also tried to call the OnLostfocus() method when navigating away from the User control. but this doesnt work either. for the most part the project swaps in and out usercontrol elements in the main xaml.cs. mainly iam not really sure how to go about getting this method to be called when the usercontrol exits without destroying the mvvm structure i have i place now. any help would be greatly appreciated.
Solution:
oKay i figured this out. In my main.xaml is had a user contorls beign swapped in and out depending on menu item press by the user. the usercontorl in the main xaml looked like this
<UserControl x:Name="ActiveUserControl" Height="Auto" Width="480" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1" Margin="0"/>
and it was swapped in and out using this command in the xaml.cs
ActiveUserControl.Content = _userControls["controlname"];
_usercontrols was just a dictionary of usercontrols. so in the onnavigatedfrom method in the main.xaml i changed the content of the ActiveuserControl to some other usercontrol. so if the home key was pressed on this usercontrol it would firethe unloaded event which fired then in the usercontol code behind this way it saved my settings.

Related

How to go back to main window from page in wpf?

On a C# application that I am working on, I have a frame on my main window.
<Frame x:Name="frame" Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" NavigationUIVisibility="Hidden"/>
I click a button on my main window, and then I use the frame that I created to navigate to a page using the code below.
//Create a new object for the page
CameraPage camera = new CameraPage();
//Navigate to the new page
frame.NavigationService.Navigate(camera);
What I would like to do is if I click a button on the camera page that is contained within the frame, then it only exits the page while still keeping the main window intact.
I have tried something like this.
NavigationService.GoBack();
But then I get an error:
System.InvalidOperationException: 'Cannot navigate because there is no entry in the Back stack of the journal.'
I believe this error is happening because the navigation stack I used to go the page is apart of the main window code and not the page that I navigated to.
So my question really is, how do I close a page contained within a frame with a button contained within the page, without closing the entire application?
If you want to end up with an empty Frame again, all you have to do is clear the Frame's contents. According to this answer, you can do so like this:
frame.Content = null;
That will get you back to how things started, now you just to trigger it. For that, I'll refer you to the question WPF Frame and Page Get event. The answer there shows you how to use DelegateCommand (a.k.a. RelayCommand) to accomplish this. This is the way I would go, because it keeps the Page nice and separate from whatever Window is hosting it.
Technically, you could also pass your Page a reference to frame when you initialize it, then have it set frame.Content = null; that way. But that's a sort of "quick and dirty" approach, not really a best practice.

CefSharp WPF and MVVM?

I am using CefSharp for WPF. I want to use it in MVVM architecture. Unfortunately there is a problem.
In the view I have:
<ContentPresenter Content="{Binding Browser}"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
In ViewModel I put a new object into Browser:
var settings = new CefSharp.Settings
{
PackLoadingDisabled = true,
}
if (CefSharp.CEF.Initialize(settings))
{
int counter = 0;
this.Browser = new WebView();
}
Unfortunately I cannot Load any URL at any point after that. It says Browser not initialized and actually the IsBrowserInitialized property (in Browser) is false.
That is weird because in test app, not MVVM, where I used same code to instantiate the WebView it works. Only difference is that I programmatically added the Browser to a Grid as it was not MVVM.
Anyone got the CefSharp in WPF MVVM app? Any ideas?
Thanks
EDIT:
I have noticed in test non-MVVM app, that the IsBrowserInitialized property is set to false until window constructor ends the job.
CefSharp version 1 is not very well suited for MVVM at the moment, unfortunately. Luckily, in CefSharp 3 I have tried to make it more "MVVM-aware" so you don't have to do a lot of hacks. See the CefSharp.Wpf.Example code there and you will (hopefully) see what I mean.
The way to get it working with CefSharp version 1.xx is to set up a PropertyChanged event handler. Once the IsBrowserInitialized property gets set to true, you can then do your work. Like this:
webView.PropertyChanged += OnWebViewPropertyChanged;
// ...
private void OnWebViewPropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "IsBrowserInitialized":
if (webView.IsBrowserInitialized)
{
webView.Load("http://some/url");
}
break;
}
}
I appreciate it's an old question and possibly answered elsewhere, but given the succinct title google may send you here (it did for me!)
The underlying ChromiumWebBrowser is very MVVM friendly..
Create the control in xaml for binding as a source/destination amongst your other controls. e.g. bind back button.
AND optionally create the control in your view model (aka MVVM), e.g. more complicated browser management such as invoking js, hooking up events, etc.
Example..
<cefSharp:ChromiumWebBrowser name="browser" WebBrowser="{Binding WebBrowser, Mode=OneWayToSource}"
Address="{Binding Address, Mode=TwoWay}"
RenderOptions.BitmapScalingMode="{Binding ElementName=scalingModeComboBox, Path=SelectedItem}" />

Showing Progressring during navigation between pages

My intention is that when a user clicks a button to navigate to another page he will see a progressring untill the other page is fully loaded.
I have found a lot of tutorials about the subject, but all of them use code behind. I want to be able to use no code-behind(if possible). I am currently using MvvmLight with the ViewModelLocater.
I have allready made a dummy grid in my views that can display the Progressring and i have bound its active and visible property's to my viewmodels.
<Grid Background="Transparent" Visibility="{Binding LoadCircleVisibility}" Height="{Binding HeigthScreen}" Width="{Binding WidthScreen}" >
<ProgressRing Height="50" Width="50" IsActive="{Binding ProgressRingActive}" Visibility="{Binding ProgressRingVisibility}"></ProgressRing>
</Grid>
I can allready display it when i'm getting data from a wcf service for example, but not when the user navigates to a different page.
At this point im trying to do this with messaging, but i am not sure where i should put the message that will make my progressring visible.
My message will always go through this method to set the correct values for the progressring:
private void ProggressBarVisible(bool visible)
{
if (visible)
{
ProgressRingVisibility = Visibility.Visible;
LoadCircleVisibility = Visibility.Visible;
}
else
{
ProgressRingVisibility = Visibility.Collapsed;
LoadCircleVisibility = Visibility.Collapsed;
}
ProgressRingActive = visible;
}
But when i want to navigate to another page there is no progressring.
So the Question is how can i display a progressring while mvvmlight is loading the new page.
Edit: partial solution:
The reason my navigation was slower and locked the uithread was because it had to buid the entire page. I changed this by making sure all the methods and logic is ut into a different thread, this ensures that my uithread continues immediatly and i can display the loadcircle on my second page while it is performing the logic and methods.
I don't know how do this without code behind
You can add root panel to the your application and put there custom control. This custom control just for showing/hiding preloader.
And when you unload 1st page(or another event) you'll show custom preloader; and when you finish to download 2nd page- you'll hide custom preloader.

Proper window design XAML (performance)

I have made an application which showns a lists of client. You can open a client, and the client's details are shown.
My application takes quite a long time to start, so I want to improve the startup performance.
In pseude-code, my main window looks like this
<Window>
<c:WelcomeAnimation Visibility="Visible" />
<c:ClientList Visibility="Collapsed" />
<c:ClientDetails Visibility="Collapsed" />
</Window>
Now, before the main window is shown, I see that the ClientList and ClientDetails are intialized. This is time consuming, so I want to delay this initialization and do it when the main window is shown and the WelcomeAnimation is running.
This will give at least the perception that the application starts faster.
Question: What are my options in window design. I like to have the above XAML view. I can of course do everything in code-behind, so my main window XAML will be nothing more than
<Window />
but maybe there are better options I'm not aware of?
This depends. When the startup time is because of code you have written yourself (e.g. calling web services or fetching data from the database), don't execute that code on initialize, but fire off a background thread/ThreadPool task and run the code there.
When the startup time is actually just because of the control being loaded (e.g. it is a very complex control with many visuals), you have two options. Either put in a replacement panel instead of the control and fill that once the animation is displayed. The second option is to just bite the bullet.
One more thing to note. If the startup times actually are because of a huge amount of visuals, the initialization will have to be done on the UI thread anyway, so the animation will not be playing while loading the control.

Help! Data binding does not work in Silverlight on Mac

I have writen a small applet in Silverlight and, while it works fine on Windows, it seems that on OSX the data binding part of the application (all those NotifyPropertyChanged calls) do not work. Does anyone know why this is? I've tried under both Firefox and Safari with the latest 2.0 download installed.
Your usage of the model object instance in Page seemed odd to me right away. It is not downright incorrect but unusual to me. Some experimentation led me to a working solution, albeit without knowing the cause of the error that happened in the first place. Not many people instantiate objects directly in the DataContext assignment, which is probably why this is not a well-known (and fixed!) defect.
Remove the DependencyObject base class from MyModel.
Make the MyModel instance be a resource of Page, instead of instantiating it directly into the DataContext.
Modify the Button_Click event handler to load the resource, instead of the named Page child object.
All done!
Code snippets for the working solution follow.
Page.xaml
<UserControl.Resources>
<my:MyModel x:Key="TheModel"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource TheModel}">
Page.xaml.cs
private void Button_Click(object sender, RoutedEventArgs e)
{
((MyModel)Resources["TheModel"]).BeginUpdateBitmap();
}
MyModel.cs
public sealed class MyModel : INotifyPropertyChanged
{
Please also include the source code with your question in the future. It would have made this quite a bit simpler.
Did you try using remote sliverlight debugging to the mac? I'd expect getting the debugger setup and turning on 1st chance exceptions has a good shot at showing you the problem.

Categories