My Dialog is a simple Frame with an Image, a label to display a question and two more labels (Yes / No) with TapCommand.
I've set up the container with the DialogPage.xaml and DialogPageViewModel and injected in the ViewModel I want to open the dialog.
Here is the code I'm using to call the Dialog:
public void ShowDialog()
{
_dialogService.ShowDialog("DiscardPopup", CloseDialogCallback);
}
void CloseDialogCallback(IDialogResult dialogResult)
{
var goBack = dialogResult.Parameters.GetValue<bool>("GoBack");
if (goBack)
NavigationService.GoBackAsync();
}
If the user taps over the "Yes label", I execute this command:
YesCommand = new DelegateCommand(() => YesTapped());
private void YesTapped()
{
IDialogParameters pa = new DialogParameters();
pa.Add("GoBack", true);
RequestClose(pa);
}
If the user taps over the "No label", I simply call:
NoCommand = new DelegateCommand(() => RequestClose(null));
The "problem" is when the ShowDialog is fired, the DiscardPopup is taking up to 3 seconds to show up.
Is there a way to make it faster?
The same happens with the TapCommands, 2 - 3 seconds when the RequestClose is invoked.
Without actual code telling you exactly what the issue is, is going to be best guess. Based on your feedback to my comments above I would suggest the following:
Try displaying the dialog on a test page that doesn't have a complex layout. My guess is that you won't see such a long load time. If that's the case this would point to your layout being overly complex and that the lag time is due to the device struggling to re-render the View
Try using Prism.Plugin.Popups. You'll need to initialize Rg.Plugins.Popup and register the DialogService. You can see docs on that at http://popups.prismplugins.com
Related
I have a function that looks like the following
void MainWindow::CreateEnvironment()
{
MdiWindow* sub = createSubWindow();
MyQTWidget* widget = CreateWidget();
..
..
}
I want that during this function a progress bar will be shown at the beggining and will close at the end of this function.
However adding
void MainWindow::CreateEnvironment()
{
**progressBarDialog->show();**
MdiWindow* sub = createSubWindow();
MyQTWidget* widget = CreateWidget();
..
..
**progressBarDialog->hide();**
}
Does not work, maybe because the function needs to exit first or something.
What is the best way to do this?
I assume that you use QProgressDialog?
You need to first setup the dialog with the correct number of steps you expect, how long you want to wait before it actually shows and more importantly: you need to call setValue() to update the progress bar.
Here is an example of how I would solve that (as far as I understand it)
void MainWindow::CreateEnvironment()
{
auto bar = new QProgressBarDialog(this);
bar->setLabelText(tr("Creating Environment..."));
bar->setCancelButton(nullptr); // No cancel button
bar->setRange(0, 10); // Let's say you have 10 steps
bar->setMinimumDuration(100); // If it takes more than 0.1 sec -> show the dialog
bar->setValue(0);
MdiWindow* sub = createSubWindow();
bar->setValue(1);
MyQTWidget* widget = CreateWidget();
..
..
bar->setValue(10);
MyLastWidget* last = CreateLastWidget();
bar->deleteLater(); // Not needed anymore, let's get rid of it
}
And don't worry too much if the dialog never shows. Unless you're doing really heavy computation (such as allocating / initialising huge portion of memory), creating widgets is very fast and would finish before the 100ms times out.
EDIT: Another thing to be aware of: QProgressDialog is meant to work after the main event loop started. (That is after the call to app.exec() in your main())
If you plan to show call this function in the constructor of your MainWindow, the dialog might even never show up because the window itself is not fully created and operational.
If you intended to call this function later, when the main window is already displayed on screen and the user hit a New Document button of some sort: you can ignore this part of the answer.
In order to verify that all changes made by the user have been saved I want to intercept the exiting/quitting of a JavaFX application.
Is there a common way-to-go to achieve this like overriding an event or is there more to it?
As they have already said, this is done by intercepting WindowEvent.WINDOW_CLOSE_REQUEST. You can then stop the suspension by calling event.consume().
This is an example of how to capture the event and display a confirmation dialog. Depending on the user's choice, you can take serialization actions if you wish.
primaryStage.setOnCloseRequest(event -> {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.initOwner(primaryStage);
alert.initModality(Modality.APPLICATION_MODAL);
alert.setHeaderText("Exit");
alert.setContentText("Do you want to exit?");
alert.getDialogPane().getButtonTypes().setAll(ButtonType.OK, ButtonType.NO);
Optional<ButtonType> optional = alert.showAndWait();
if(optional.isPresent() && optional.get() == ButtonType.OK) {
// save data
return;
}
event.consume();
});
In order for the implementation to be complete, you need to implement a logic for clear exit from the application from control. For example, when choosing from the File menu -> Close. When capturing the event, you must run WindowEvent.WINDOW_CLOSE_REQUEST to trick the exit logic.
closeMenuItem.setOnAction(event -> {
Window window = menuBar.getScene().getWindow();
window.fireEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSE_REQUEST));
});
In the class Application there is the stop method which you can override possibly.
I have an activity indicator on xaml page. Initially its IsVisible property is false. I have a button on page. When user click on button it calls a web service to get data. I change the value of IsVisible property to true before calling the service so that activity indicator starts to display on page and after successful calling of service I change its value to again false so that it doesn't show any more on page.
But it is not working. I know the actual problem. When we call the web service the UI thread gets block and it doesn't show the activity indicator.
How I can enable the UI thread when web service gets called so that activity indicator can show on page until we get the data?
Try making your webservice call into an async and await it.
Depending on how you've structured things you may have to use a TaskCompletionSource as the following example demonstrates.
In this example when the button is clicked, the button is made invisible, and the ActivityIndicator is set to IsRunning=True to show it.
It then executes your long running task / webservice in the function ExecuteSomeLongTask using a TaskCompletionSource.
The reason for this is that in our button click code, we have the final lines:-
objActivityIndicator1.IsRunning = false;
objButton1.IsVisible = true;
That stop the ActivityIndicator from running and showing, and also set the button back to a visible state.
If we did not use a TaskCompletionSource these lines would execute immediately after calling the ExecuteSomeLongTask if it was a normal async method / function, and would result in the ActivityIndicator not running and the button still being visible.
Example:-
Grid objGrid = new Grid()
{
};
ActivityIndicator objActivityIndicator1 = new ActivityIndicator();
objGrid.Children.Add(objActivityIndicator1);
Button objButton1 = new Button();
objButton1.Text = "Execute webservice call.";
objButton1.Clicked += (async (o2, e2) =>
{
objButton1.IsVisible = false;
objActivityIndicator1.IsRunning = true;
//
bool blnResult = await ExecuteSomeLongTask();
//
objActivityIndicator1.IsRunning = false;
objButton1.IsVisible = true;
});
objGrid.Children.Add(objButton1);
return objGrid;
Supporting function:-
private Task<bool> ExecuteSomeLongTask()
{
TaskCompletionSource<bool> objTaskCompletionSource1 = new TaskCompletionSource<bool>();
//
Xamarin.Forms.Device.StartTimer(new TimeSpan(0, 0, 5), new Func<bool>(() =>
{
objTaskCompletionSource1.SetResult(true);
//
return false;
}));
//
return objTaskCompletionSource1.Task;
}
You need to do your work in an asynchronous way. Or in other words: Use Asnyc & Await to ensure, that you UI works well during the call.
You can find more informations in the Xamarin Docs.
async and await are new C# language features that work in conjunction
with the Task Parallel Library to make it easy to write threaded code
to perform long-running tasks without blocking the main thread of your
application.
If you need further asistance, please update your question and post your code or what you have tried so far.
I am trying to switch to a New window which gets displayed when I click on the Debt Pricing Template. But I am unable to do that as a result of which I am not able to proceed with further scripting... The problem is I am not able to know what should I pass in the switchTo.window() because Pricing Approval Gateway window displays and following is the HTML for the new window:
<*h1 class="pageType noSecondHeader">Pricing Approval Gateway<*/h1>
Following is the code:
LoginPage2.driver.findElement(By.linkText("TEST ORG")).click();
System.out.println("3.Select Dept pricing template button from the organization detail page.");
if(LoginPage2.driver.findElement(By.name("debt_pricing_template")).isDisplayed())
System.out.println("User should able to navigate to Dept pricing template and template display few question, user have answer these question for further navigation.");
LoginPage2.driver.findElement(By.name("debt_pricing_template")).click();
LoginPage2.driver.manage().timeouts().implicitlyWait(100, TimeUnit.SECONDS);
LoginPage2.driver.switchTo().window("bPageTitle");
Please advise what needs to be added?
I never used it because in my tests I am not using any new windows, but this should help:
Set<string> handlers = driver.getWindowHandles();
if (driver.getWindowHandles().size()>= 1){
for(String handler : handlers){
driver.switchTo().window(handler);
if (driver.getElement(By.tagName("h1")).contains("Pricing")){
System.out.println("Get focus on Popup window");
break;
}
}
}
else System.out.println("No windows founded!");
I am not quite sure with the h1 approach. So if it does not help, try before opening new window storing current window to String:
String mainWindow = driver.getWindowHandle();
Then click the link (or do something else as you are doing now) to open new window. Then to switch to the new window:
Set<string> handlers = driver.getWindowHandles();
for (String handler : handlers){
if (!handler.equals(mainWindow)){
driver.switchTo(handler);
break;
}
}
And then to switch back to original window just do:
driver.switchTo(mainWindow);
Ofcourse the driver variable is expected live instance of
WebDriver
driver.findElement(By.linkText("Go to Billing Summary")).click();
driver.findElement(By.linkText("01 Mar 2016")).click();
Thread.sleep(5000);
driver.findElement(By.linkText("AMS TAX")).click();
driver.findElement(By.linkText("00842")).click();
Set<String> instancewindow= driver.getWindowHandles();
Iterator<String> it = instancewindow.iterator();
String parent =it.next();
String child = it.next();
driver.switchTo().window(child);
driver.switchTo().frame("modalSubWindow");
driver.findElement(By.linkText("View More Vehicle Details>>")).click();
driver.switchTo().window(parent);
EDIT 4:
EDIT 3
EDIT 2
string currentWindow = driver.CurrentWindowHandle;
driver.SwitchTo().Window("");
string childTitle = driver.Title;
driver.SwitchTo().Window(currentWindow);
string parentTitle = driver.Title;
the above code gives me the same title for parent window or child window.
EDIT:
<a id="ctl00_ctl00_Features_ctl03_lnkPage" class="title" target="_blank" href="websiteaddress">Stay Around</a>
how to verify the title of a newly window open and once i verified then close the opened new window?
so in my page I have a link and click on the link and it opens a new window and now I am not sure how to verify the title of that window.
here is what i have done so far.
GoToMysiteUrl();
IWebElement addtoList = driver.FindElement(By.XPath(_pageName));
addtoList.Click();
//it opens a new window
now i want to switch focus on the new window and verify the title and close the new window
back to the previous window.
The piece that most people miss when dealing with popup windows in IE is that a click on an element is asynchronous. That is to say, if you check the .WindowHandles property immediately after a click, you may lose the race condition, because you're checking for the existence of a new window before IE has had the chance to create it, and the driver has had a chance to register it exists.
Here's the C# code I would use to perform the same operation:
string foundHandle = null;
string originalWindowHandle = driver.CurrentWindowHandle;
// Get the list of existing window handles.
IList<string> existingHandles = driver.WindowHandles;
IWebElement addtoList = driver.FindElement(By.XPath(_pageName));
addtoList.Click();
// Use a timeout. Alternatively, you could use a WebDriverWait
// for this operation.
DateTime timeout = DateTime.Now.Add(TimeSpan.FromSeconds(5));
while(DateTime.Now < timeout)
{
// This method uses LINQ, so it presupposes you are running on
// .NET 3.5 or above. Alternatively, it's possible to do this
// without LINQ, but the code is more verbose.
IList<string> currentHandles = driver.WindowHandles;
IList<string> differentHandles = currentHandles.Except(existingHandles).ToList();
if (differentHandles.Count > 0)
{
// There will ordinarily only be one handle in this list,
// so it should be safe to return the first one here.
foundHandle = differentHandles[0];
break;
}
// Sleep for a very short period of time to prevent starving the driver thread.
System.Threading.Thread.Sleep(250);
}
if (string.IsNullOrEmpty(foundHandle))
{
throw new Exception("didn't find popup window within timeout");
}
driver.SwitchToWindow(foundHandle);
// Do whatever verification on the popup window you need to, then...
driver.Close();
// And switch back to the original window handle.
driver.SwitchToWindow(originalWindowHandle);
Incidentally, if you're using the .NET bindings, you have access to a PopupWindowFinder class in the WebDriver.Support.dll assembly, which uses a very similar approach to the locating popup windows. You may find that class meets your needs exactly, and can use it without modification.
GoToMysiteUrl();
IWebElement addtoList = driver.FindElement(By.XPath(_pageName));
addtoList.Click();
// Post above operation a new window would open as described in problem
// Get hold of Main window's handle
string currentWindow = Driver.CurrentWindowHandle;
// Switch to the newly opened window
Driver.SwitchTo().Window("Your Window Name");
// Perform required Actions/Assertions here and close the window
// Switch to Main window
Driver.SwitchTo().Window(currentWindow);