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.
Related
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.
I am new in WPF and want to create WPF application like cookbook. I already done this and app work correctly. But I make it in this way:
First screen show buttons, which open new windows to do something. As a result i have 14 different windows. It is ok, but now i want to make it in other way.
I am trying to make one window, which will be showed at start, and change content. I divided window on two grids. First is static and is placed on bottom. It contains buttons, which represents functionality of the program. Second one will be dynamic. There i want to show content of every window. So i want to change content of this panel instead of creating new windows.
I tried to make *.cs files which will create controls in code-behind, functions and data. But my idea is not succesful and i do not know how to do this.
At all, I want to create app, which will work like this:
- if you click button "Add receip" then app will show controls to add name, ingredients and save it at the end.
- if you clik "Show receip" previous content will be replaced by list of ingredients
and etc.
I hope you will understand me.
You can create a Frame instead of second grid. Frame allows you to show pages, and not in seperate windows, in Frame itself. You can navigate the frame into the page like
mainFrame.Source = new Uri("Page1.xaml",UriKind.Relative);
This changes the frame to your page. You can change the source again, if you wanna change the page again.
Note: You can add tags to your buttons like "showReceip" and you can make just one buttonclick event for your buttons. Code will look like this.
mainFrame.Source = new Uri((sender as Button).Tag.ToString() + ".xaml",UriKind.Relative);
That takes the tag of your clicked button, add the string ".xaml" on it and take it on the source part. So, if your tag is "Page1", Source will look like "Page1.xaml" as my solution.
Appreciate the try, I hope you are looking for WPF user controls instead for separate windows. User controls are similar to windows you can create the UI and functionalities in the user control. I would like to recommend you to design the main window like the following:
<Grid>
<Canvas Name="canFunctionalButtons">
<!--Define the buttons inside this canvas
And allocate proper place for this in the UI
-->
</Canvas>
<Canvas Name="canControlContainer">
<!--This is to display the user control
Which can be changed dynamically according to the Button's click
-->
</Canvas>
</Grid>
Then you have to add click event for those buttons, which will add specific user control to the canControlContainer canvas. An example for adding an user control to this canvas is as follows, Let btnAddSomething be a button and btnAddSomething_Click be its click event then you can do something like:
private void btnAddSomething_Click(object sender, RoutedEventArgs e)
{
canControlContainer.Children.Clear(); // will remove previous contols from this canvas
// UC_AddSomething be the user control that you wanted to add here
canControlContainer.Children.Add(new UC_AddSomething());
}
I am building a WPF app that needs numeric input from user. I am using NavigationWindow and have built a Page that contains a numeric keypad. The app needs numeric input more than once. Inspired by this, I want to put numeric Page inside a Frame inside a Popup as follows:
<Grid Name="mainDisplay">
<Popup Name="popupDialog" PlacementTarget="{Binding ElementName=aInputBox Placement="Center">
<StackPanel>
<Frame Source="MyNumpad.xaml"/>
<Button Click="OK_Outside_Click">Ok_Outside_Numpad</Button>
</StackPanel>
</Popup>
// invalid comment and other stuff in grid....
</Grid>
When the "Ok_Outside_Numpad" Button is clicked, the numpad disappears and the main page is re-enabled. Code as follows:
private void OK_Outside_Click(object sender, RoutedEventArgs e)
{
popupDialog.IsOpen = false;
mainDisplay.IsEnabled = true;
}
Two questions:
There is already an "OK" button inside MyNumpad.xaml. Is it possible to access the mainDisplay and popupDialog clicking Ok_Inside_Numpad button? How can I pass variables to
MyNumpad constructor?
How to get the user numeric input when MyNumpad exits?
Thanks! Note that I am new to WPF, not sure if my approach is any good. Any idea is welcomed!
The correct approach is binding the Views (NavigationWindow and MyNumpad.xaml) to a ViewModel (or several ViewModels). With data binding, you simply set a value to false to close the Popup (since the Popup's IsOpen property is bound to that value). It does not matter where a control resides since you don't need to manipulate controls in your code.
But before reading that long article and begin to learn MVVM, you can make some modification to your code to make it work.
You can't access MainPage elements from the hosted page, as the hosted page has no reference to the MainPage. As you have thought about, you can pass MainPage to the constructor of MyNumpad (do it in code, and remember to modify MyNumpad's constructor).
public MainWindow()
{
InitializeComponent();
MyNumpad numpad = new MyNumpad(this);
frame1.Navigate(numpad);
}
Then you can access MainPage elements from the Popup Page.
But it is easier to add a Click event handler to the Popup's button, because the event handler is defined inside MainWindow, it has access to all controls in MainWindow. (Remember to delete the event handler defined inside MyNumpad.)
string strNumber;
public MainWindow()
{
InitializeComponent();
MyNumpad numpad = new MyNumpad();
numpad.button1.AddHandler(Button.ClickEvent, new RoutedEventHandler(
(s, e) =>
{
//suppose there is a TextBox in the page to accept user input
strNumber = numpad.InputTextBox.Text;
popupDialog.IsOpen = false;
mainDisplay.IsEnabled = true;
}), false);
frame1.Navigate(numpad);
}
I am developing WPF MUI application.I navigate to another page using button onclick and print some text on page1.xaml . after i navigate using another button to print another text on page1.xaml .but i could not do that.my out put was not new text.it is early details only.can't reload page1.xaml .when navigating I pass the parameter and according to parameter print deference text on same page.can anyone help me?
this is my navigation code
var frame = NavigationHelper.FindFrame(null, this);
frame.Source = new Uri("../Content/Sale/SaleInvoice/Nested/saleNested.xaml", UriKind.Relative);
Have the page databound to a ViewModel. Once you want to refresh just create a new Viewmodel. It would make sense to have the execution of the reloading being done in a backgroudworker so your UI stays responsive. This is esspecially usefull if you are refreshing some resource from a webService or some other online source.
The Data bind to the page at the initial time to reload the page I'm using this method
On xaml page just add Loaded Property:
<UserControl x:Class="ModernUINavigationApp1.Pages.Page"
...
Loaded="OnLoad" >
Then Add event handler in code behind to make the page do whatever you want when it's loaded
private void OnLoad(object sender, RoutedEventArgs e)
{
}
Hope this help :D
Make sure your ViewModel implements INotifyPropertyChanged. If your Page1.xaml's DataContext is set to the ViewModel, and your XAML uses bindings properly, any change to the ViewModel will be reflected in the UI. You won't need to refresh anything. Just update the property in the ViewModel object.
If you update your question with example XAML and C#, I can be of more help.
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.