When I click to button, page of pop-up is opening. I have to click button on it. How can I do it?
await page.GoToAsync("https://.....");```
await page.WaitForTimeoutAsync(7000 * 2);```
await page.WaitForSelectorAsync("a[class='visit_button']");```
await page.ClickAsync("a[class='visit_button']"); //open popup```
await page.WaitForTimeoutAsync(3000);```
// I click to button on pop-up```
This works for me:
var alertMessage = "";
//attach to page during entire page life-cycle (until closed).
//handles the case where an javscript alert comes up during login.
page.Dialog += new EventHandler<DialogEventArgs>(async (sender, args) =>
{
alertMessage = args.Dialog.Message;
await args.Dialog.Accept(); //this closes it..
Log.Information("Popup squashed in Login(): {0}", alertMessage);
Thread.Sleep(500);
});
According to PageEventsPopupTests :
await page.GoToAsync("https://.....");
await page.ClickAsync("a[class='visit_button']"); //Open Popup
var popupTaskSource = new TaskCompletionSource<Page>();
page.Popup += (_, e) => popupTaskSource.TrySetResult(e.PopupPage);
await popupTaskSource.Task;
var popupPage = popupTaskSource.Task.Result; // Popup Page
await popupPage.ClickAsync("a[class='btn']"); //Click on button in popup page
Related
I want when a user clicks an inline button, a message sent to another user!
Here is my code:
//creating inline keyboard
InlineKeyboardButton accept= new InlineKeyboardButton();
InlineKeyboardButton reject = new InlineKeyboardButton();
InlineKeyboardButton[] buttons = new InlineKeyboardButton[]
{
accept, reject
};
InlineKeyboardMarkup inline = new InlineKeyboardMarkup(buttons);
//giving inline buttons text and callback data
accpet.Text = "accept";
reject.Text = "reject";
accept.CallbackData = "accept";
reject.CallbackData = "reject";
//instantiation "CallbackQuery" class
CallbackQuery callbackQuery = new CallbackQuery();
//send a text message to someone else if "callbackQuery.Data" was same a "accept" button callback data.
//This Part Doesn't Works. When I click accept button it does nothing!
if (callbackQuery.Data == "accept")
{
await botClient.SendTextMessageAsync(
chatid,
"Hello World."
);
}
Thanks A lot For Your Helps :)
You're doing wrong, You should wait until receiving CallbackQuery update, Not creating new CallbackQuery(); And then try processing.
Telegram has something called Updates, Which means events when new message sent Or edited, Button pressed, User joined, etc.
So, You should create a OnCallbackQuery event, To handle any callback button pressed like this:
First, Creating the handler method:
botClient.OnCallbackQuery += botClient_OnCallbackQuery;
private void botClient_OnCallbackQuery(object sender, CallbackQueryEventArgs e)
{
// Send the message to any one you want
ChatId chatId = /*Put any chat ID you want*/;
await botClient.SendTextMessageAsync(chatId, "Hello World.");
}
Second, You should handle any message via OnMessage event like this:
botClient.OnMessage += botClient_OnMessage;
private async void botClient_OnMessage(object sender, MessageEventArgs e)
{
var message = e.Message;
if (message.text == '/start')
{
var accept = InlineKeyboardButton.WithCallbackData("Accept", "accept");
var reject = InlineKeyboardButton.WithCallbackData("Reject", "reject");
await botClient.SendTextMessageAsync(message.Chat.Id, "Accept Or Reject..", replyMarkup: new InlineKeyboardMarkup([accept, reject]));
}
}
When I open the application it works perfect. But when I use my scan button again it's stuck on a white screen and not passing until I press the "Back" Button on my phone.
How can I remove that white screen bug?
Video about my bug: https://www.youtube.com/watch?v=k8-haOmCzm0
QR Code Scanner Code:
public async void Scan()
{
var scan = new ZXingScannerPage();
await Navigation.PushAsync(scan);
scan.OnScanResult += (result) =>
{
Device.BeginInvokeOnMainThread( () =>
{
Navigation.PopAsync();
codes.Text = result.Text;
Application.Current.Properties["codes"] = codes.Text;
Navigation.PushAsync(new MainPage());
});
};
}
My Scan again button Code:
private void Button_Clicked_1(object sender, EventArgs e)
{
Navigation.PushAsync(new ScanPage());
}
From shared code, you have pushed twice to the scan page, however you only use one time PopAsync after get result.
But also used the third push in Device.BeginInvokeOnMainThread:
Navigation.PushAsync(new MainPage());
You could modiy this line with following code to check whether it works.
Device.BeginInvokeOnMainThread( () =>
{
Navigation.PopAsync();
codes.Text = result.Text;
Application.Current.Properties["codes"] = codes.Text;
Navigation.PopAsync();
});
============================Update================================
If you scan code when lauching application, when receiving results, you could use Application.Current.MainPage = new MainPage(); to back to Root Page of Applicatuon.
Code as follows:
Device.BeginInvokeOnMainThread( () =>
{
Navigation.PopAsync();
codes.Text = result.Text;
Application.Current.Properties["codes"] = codes.Text;
Application.Current.MainPage = new MainPage();
});
Is there a way to wrap the UWP async function for creating dialog boxes in such a way that they can be called from a normal method without the async keyword? Example:
var msgbox = new ContentDialog
{
Title = "Error",
Content = "Already at the top of the stack",
CloseButtonText = "OK"
};
await msgbox.ShowAsync();
No, there is no way to do this at the moment. If you try to block waiting for the dialog to close, your app will deadlock.
Here is how I do it (I saw this in some live demo back when UWP was just introduced):
var msgbox = new ContentDialog
{
Title = "Error",
Content = "Already at the top of the stack",
CloseButtonText = "OK"
};
var ignored = msgbox.ShowAsync();
This works as expected in a non-async void method.
public Task<ContentDialogResult> MsgBox(string title, string content)
{
Task<ContentDialogResult> X = null;
var msgbox = new ContentDialog
{
Title = title,
Content = content,
CloseButtonText = "OK"
};
try
{
X = msgbox.ShowAsync().AsTask<ContentDialogResult>();
return X;
}
catch {
return null;
}
}
private void B1BtnBack_Click(object sender, RoutedEventArgs e)
{
MsgBox("Beep", "Already at the top of stack");
return;
// ^^^ Careful here. MsgBox returns with an active task
// running to display dialog box. This works because
// the next statement is a return that directly
// returns to the UI message loop. And the
// ContentDialog is modal meaning it disables
// the page until ok is clicked in the dialog box.
}
I am using the following alert in the mvvmcross, I wonder how could I able to add a cancel button.
var alertConfig = new AlertConfig {
Message = "it is not valid",
OkText = "Okely",
OnOk = () => { Debug.WriteLine("ok pressed"); }
};
Mvx.Resolve<IUserDialogs>().Alert(alertConfig);
You probably want to use Confirm instead. Alert, as the name implies, is to Alert the user to something, and the only action is to dismiss the Alert.
Individually, all code works perfectly. The snippet for saving the file, the snippet for picking a directory to save it to and also the message dialog works great.
But when I tie it all together, I get an access denied. I am not using the DocumentsLibrary capability since it is not required of me to do so in this case, however, enabling this capability after running into issues confirmed that it is not the issue.
Scenario:
User wants to create a new document after entering text in the text box. A MessageDialog appears, asking them if they want to save changes to the existing file first - the user clicks Yes (save file).
Now, here is where you handle the event that was raised by the MessageDialog.
Inside the IUICommand command event handler, you test for which button was clicked, and act accordingly.
I did this with a switch statement:
switch(command.Label) {
case "Yes":
SaveFile(); // extension method containing save file code that works on its own
break;
case "No":
ClearDocument();
break;
default:
break;
}
Now, each case works great except for the Yes button. When you click yes, an e tension method is called which has code that saves to a file
It is when you click yes button that you get the ACCESS DENIED exception. Details of the exception didn't reveal anything.
I think that it has something to do with how I am using the MesaageDialog. But after searching for hours I have yet to find a sample on how to save a file with the FileSavePicker when a MesaageDialog button is pressed.
Any ideas in how this should be done?
Update w/ Code
When the user clicks the New document button on the AppBar, this method fires:
async private void New_Click(object sender, RoutedEventArgs e)
{
if (NoteHasChanged)
{
// Prompt to save changed before closing the file and creating a new one.
if (!HasEverBeenSaved)
{
MessageDialog dialog = new MessageDialog("Do you want to save this file before creating a new one?",
"Confirmation");
dialog.Commands.Add(new UICommand("Yes", new UICommandInvokedHandler(this.CommandInvokedHandler)));
dialog.Commands.Add(new UICommand("No", new UICommandInvokedHandler(this.CommandInvokedHandler)));
dialog.Commands.Add(new UICommand("Cancel", new UICommandInvokedHandler(this.CommandInvokedHandler)));
dialog.DefaultCommandIndex = 0;
dialog.CancelCommandIndex = 2;
// Show it.
await dialog.ShowAsync();
}
else { }
}
else
{
// Discard changes and create a new file.
RESET();
}
}
And the FileSavePicker stuff:
private void CommandInvokedHandler(IUICommand command)
{
// Display message showing the label of the command that was invoked
switch (command.Label)
{
case "Yes":
MainPage rootPage = this;
if (rootPage.EnsureUnsnapped())
{
// Yes was chosen. Save the file.
SaveNewFileAs();
}
break;
case "No":
RESET(); // Done.
break;
default:
// Not sure what to do, here.
break;
}
}
async public void SaveNewFileAs()
{
try
{
FileSavePicker saver = new FileSavePicker();
saver.SuggestedStartLocation = PickerLocationId.Desktop;
saver.CommitButtonText = "Save";
saver.DefaultFileExtension = ".txt";
saver.FileTypeChoices.Add("Plain Text", new List<String>() { ".txt" });
saver.SuggestedFileName = noteTitle.Text;
StorageFile file = await saver.PickSaveFileAsync();
thisFile = file;
if (file != null)
{
CachedFileManager.DeferUpdates(thisFile);
await FileIO.WriteTextAsync(thisFile, theNote.Text);
FileUpdateStatus fus = await CachedFileManager.CompleteUpdatesAsync(thisFile);
//if (fus == FileUpdateStatus.Complete)
// value = true;
//else
// value = false;
}
else
{
// Operation cancelled.
}
}
catch (Exception exception)
{
Debug.WriteLine(exception.InnerException);
}
}
Any progress on this issue? I currently have the same problem. I have also found that the same problem occurs if a second MessageDialog is shown in the IUICommand event.
My solution is to cancel the first operation (that shows the first message dialog). Here some code I’m using (it’s accessible in a global object):
private IAsyncInfo mActiveDialogOperation = null;
private object mOperationMutex = new object();
private void ClearActiveOperation(IAsyncInfo operation)
{
lock (mOperationMutex)
{
if (mActiveDialogOperation == operation)
mActiveDialogOperation = null;
}
}
private void SetActiveOperation(IAsyncInfo operation)
{
lock (mOperationMutex)
{
if (mActiveDialogOperation != null)
{
mActiveDialogOperation.Cancel();
}
mActiveDialogOperation = operation;
}
}
public void StopActiveOperations()
{
SetActiveOperation(null);
}
public async void ShowDialog(MessageDialog dialog)
{
StopActiveOperations();
try
{
IAsyncOperation<IUICommand> newOperation = dialog.ShowAsync();
SetActiveOperation(newOperation);
await newOperation;
ClearActiveOperation(newOperation);
}
catch (System.Threading.Tasks.TaskCanceledException e)
{
System.Diagnostics.Debug.WriteLine(e.Message);
}
}
So every time I want to show a MessageDialog I call ShowDialog. This will cancel the current dialog if any (then a TaskCanceledException occurs).
In the case when I will use a FileSavePicker, I call StopActiveOperations before PickSaveFileAsync is called.
This works but I can’t say I like it. It feels like I’m doing something wrong.
OK, now I have figured it out :-). The documentation says explicit that you shouldn’t show new popups/file pickers in the UICommand:
http://msdn.microsoft.com/en-US/library/windows/apps/windows.ui.popups.messagedialog.showasync
This is an example of a bad way to do it:
private async void Button_Click(object sender, RoutedEventArgs e)
{
MessageDialog dialog = new MessageDialog("Press ok to show new dialog (the application will crash).");
dialog.Commands.Add(new UICommand("OK", new UICommandInvokedHandler(OnDialogOkTest1)));
dialog.Commands.Add(new UICommand("Cancel"));
await dialog.ShowAsync();
}
private async void OnDialogOkTest1(IUICommand command)
{
MessageDialog secondDialog = new MessageDialog("This is the second dialog");
secondDialog.Commands.Add(new UICommand("OK"));
await secondDialog.ShowAsync();
}
This is the correct way to do it:
private async void Button_Click_1(object sender, RoutedEventArgs e)
{
MessageDialog dialog = new MessageDialog("Press ok to show new dialog");
UICommand okCommand = new UICommand("OK");
UICommand cancelCommand = new UICommand("Cancel");
dialog.Commands.Add(okCommand);
dialog.Commands.Add(cancelCommand);
IUICommand response = await dialog.ShowAsync();
if( response == okCommand )
{
MessageDialog secondDialog = new MessageDialog("This is the second dialog");
secondDialog.Commands.Add(new UICommand("OK"));
await secondDialog.ShowAsync();
}
}
Quite simple actually, I should have get this earlier...