How can I create a confirm dialog in windows phone 7?
I have an app in which I can delete items, but when someone clicks delete, I want to get him a confirm dialog where they can click 'confirm' or 'abort'
How could I do this?
you can use this:
if(MessageBox.Show("Are you sure?","Delete Item", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
{
//Delete Sentences
}
Shows a dialog something like this:
Here is the method I use. By the way for a better user experience and for consistencies sake consider using the words "delete" and "cancel" rather than "confirm" or "abort".
public static MessagePromptResult Show(string messageBoxText, string caption, string button1, string button2)
{
int? returned = null;
using (var mre = new System.Threading.ManualResetEvent(false))
{
string[] buttons;
if (button2 == null)
buttons = new string[] { button1 };
else
buttons = new string[] { button1, button2 };
Microsoft.Xna.Framework.GamerServices.Guide.BeginShowMessageBox(
caption,
messageBoxText,
buttons,
0, // can choose which button has the focus
Microsoft.Xna.Framework.GamerServices.MessageBoxIcon.None, // can play sounds
result =>
{
returned = Microsoft.Xna.Framework.GamerServices.Guide.EndShowMessageBox(result);
mre.Set(); // could have done it all without blocking
}, null);
mre.WaitOne();
}
if (!returned.HasValue)
return MessagePromptResult.None;
else if (returned == 0)
return MessagePromptResult.Button1;
else if (returned == 1)
return MessagePromptResult.Button2;
else
return MessagePromptResult.None;
}
You will need to add a reference to Microsoft.Xna.Framework.GamerServices to your project.
Rather than asking the user to confirm deletion, have you considered giving the user the ability to "un-delete" items?
While this may be a little bit more work, when it makes sense in teh context of the app it can lead to a much better user experience.
If OK / Cancel is good enough for you, you could stick to the regular MessageBox.Show
Related
When a Windows Form has the focus you can step through any Controls that have their TabStop Property set True, in Tabindex Order, by pressing the {TAB} Key.
Similarly, you can step through them in reverse order using {Shift+ TAB}
Is there any Keyboard Shortcut to move the Focus to a Known, or Absoulte, Tabindex (for example the Lowest or Highest), rather than moving it Relative to the Active Control?
If so does MS document this anywhere?
There's nothing out of the box to do this, AFAIK. You'd need to do it yourself. However, it's not that difficult, you just need to check for a hotkey by overriding the ProcessCmdKey method and then call Control.Focus() for the appropriate control:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.D1))
{
textBox1.Focus();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
You can even take it a step further to have shortcuts for several controls and also have the ability to manage the controls and their shortcuts at run-time by having a dictionary that holds the shortcuts and the controls to be focused:
Dictionary<Keys, Control> FocusShortcuts;
public Form1()
{
InitializeComponent();
FocusShortcuts = new Dictionary<Keys, Control>();
FocusShortcuts.Add(Keys.Control | Keys.D1, textBox1);
FocusShortcuts.Add(Keys.Control | Keys.D2, textBox2);
FocusShortcuts.Add(Keys.Control | Keys.D3, textBox3);
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
Control control;
if (FocusShortcuts.TryGetValue(keyData, out control))
{
control.Focus();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
Update
If instead, you want to set the focus to a control by its Tab Order, you can replace textBox1.Focus(); with something like this:
int someIndex = 5;
Control control = this.Controls.OfType<Control>()
.FirstOrDefault(c => c.TabIndex == someIndex);
if (control != null) control.Focus();
You'd just need to change the value of someIndex to the index of your choice and change this with the control's container (you can leave it if the container is the current form/UserControl).
I'm using bot-Framework SDK3 C#.
I want to allow user input anything which is not in "PromptDialog.Choice"'s options. Any better ways to recommend?
This is my code.
private async Task SelectCategory(IDialogContext context)
{
List<string> options = new List<string>();
options = category.Keys.ToList();
options.Add("Category1");
options.Add("Category2");
options.Add("Category3");
PromptOptions<string> promptOptions = new PromptOptions<string>(
prompt: "which one do you prefer?",
tooManyAttempts: "",
options: options,
attempts: 0);
PromptDialog.Choice(context: context, resume: ResumeAfterSelectCategory, promptOptions: promptOptions);
await Task.FromResult<object>(null);
}
private async Task ResumeAfterSelectCategory(IDialogContext context, IAwaitable<string> result)
{
try
{
selected = await result;
}
catch (Exception)
{
// if the user's input is not in the select options, it will come here
}
}
But the problem is it always send the message "tooManyAttempts". If I set it to empty, I will send me "0".
I suppose you are using NodeJS. You can use the simple builder.Prompts.choice with maxRetries set to 0. Here is a sample snippet. It asks user to choose some option from a list, or they can enter something which is not in the list.
If you are using C# SDK, you can find some similar option for the list.
bot.dialog("optionalList", [
function(session){
builder.Prompts.choice(
session,
"Click any button or type something",
["option1", "option2", "option3"],
{maxRetries: 0} // setting maxRetries to zero causes no implicit checking
)
},
function(session, result){
// something from the list has been clicked
if(result.response && result.response.entity){
console.log(result.response.entity); // use the clicked button
} else {
console.log(session.message.text) // if user entered something which is not in the list
}
}
]);
EDIT 1:
Hi, Saw that you are using C# SDK. I am not that proficient with that but I can give you some suggestion.
The list which you generate in the async task SelectCategory you can generate in some other place, which is also accessible to the second async task ResumeAfterSelectCategory, (like making it a class variable or getting from database).
Now that the list is accessible in the 2nd task, you can compare what user has typed against the list to determine if the message is from the list or not.
If message is something from the list, then take action accordingly, otherwise user has entered something which is not in the list, and then take action accordingly.
Your 2nd problem is
And if user typed, it will show a message "you tried to many times"
What is meant by that? Does bot sends "you tried to many times" to the bot visitor. In which case it could be the behavior of library. You will be able to control that only if library provides some option. Else I don't know. Hope, that helps
EDIT 2:
I came across this SO question Can I add custom logic to a Bot Framework PromptDialog for handling invalid answers?
You can use that questions answer. Basically extending PromptDialog.PromptChoice<T>.Here is an example.
Override TryParse method like this
protected override bool TryParse(IMessageActivity message, out T result)
{
bool fromList = base.TryParse(message, out result);
if (fromList)
{
return true;
} else {
// do something here
return true; // signal that parsing was correct
}
}
I used node.js and to get message which user entered. use this code snippet.
(session, args) => {
builder.Prompts.text(session, "Please Enter your name.");
},
(session, args) => {
session.dialogData.username = args.response;
session.send(`Your user name is `${session.dialogData.username}`);
}
I'm presenting the user with 4 choices via the PromptDialog.choice method. In my Resume method, I want to forward the user to a dialog to handle their choices. I no longer have access to the current MessageActivity object
and wonder what my options are? I'd like to pass the original Message if at all possible. Passing an empty one seems like a hack. And the dialog PrintGraphicDialog will just display a graphic image and return back to the 4 choices. using Context.Call hits the PrintGraphicDialog's StartAsync method and has the context.wait() call which requires the user to type something. Then it prints the graphic. Not quite what is wanted either.
private void ShowOptions(IDialogContext context)
{
PromptDialog.Choice(context, this.OnOptionSelected, new List<string>() { OptionOne, OptionTwo, OptionThree, OptionFour }, "Please select from the following options:", "Not a valid option", 3);
}
private async Task OnOptionSelected(IDialogContext context, IAwaitable<string> result)
{
try
{
string optionSelected = await result;
switch (optionSelected)
{
case OptionOne:
await context.Forward(new PrintGraphicDialog(), this.ResumeAfterOptionDialog, context.MakeMessage(), CancellationToken.None);
break;
case OptionTwo:
break;
case OptionThree:
break;
case OptionFour:
break;
}
}
catch (TooManyAttemptsException ex)
{
}
}
You can store the message in a variable right before calling your PromptDialog.Choice and then use it in the Resume method.
Since the dialog I was forwarding control to really only needs a few properties from the original message, I just created a class, stored them in there and before forwarding, did context.MakeMessage() and populated that with the stored off properties. Seems like there should be a better way.
I have build a login form using two TextInput fieldds for username and password. I have already created a button which was straightforward. I want the user to have the option of pressing Enter on the keyboard to log in and not click on the button. How do I do that? And, can you please explain what the Event.Change does? Many thanks
You could listen to KeyboardEvent.KEY_DOWN, which is dispatched while the key is pressed. You could stop listening as soon as this had occurred.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/events/KeyboardEvent.html
And then look up the keyCode for the Enter key (13). http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00000520.html
Example:
public static const ENTER:int = 13;
public var pressedEnter:Boolean = false;
public function start():void
{
passwordField.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown,
false, 0, true);
}
private function onKeyDown(e:KeyboardEvent):void
{
if (!pressedEnter && ENTER == e.keyCode) {
trace("TODO: Enter form.");
pressedEnter = true;
}
}
Event.CHANGE dispatches every time text field changing, or an option in a widget changing to a different option.
stage.addEventListener(KeyboardEvent.KEY_DOWN, key_down);
function key_down(e:Event):void
{
//whatever you want
}
I need to navigate to a certain page the first time my app is run, to gather login details etc. I'm using IsloatedStorageSettings to save a value to determine if this is the first run of the app or not, which works fine.
My problem is actually navigating to my 'first run' page when the app is run for the first time, using NavigationService, it seems NavigationService is not created at this point so is still null. When is NavigationService created or how can I work around this?
My code (in the constructor of my main page:
if ((bool)settings["firstRun"])
{
if (NavigationService != null)
{
NavigationService.Navigate(new Uri("/FirstRun.xaml", UriKind.Relative));
}
else
{
MessageBox.Show("Navigation service must be null?"); //always prompts
}
}
else
{
InitializeComponent();
}
Peter Torr has a great blog post on the ins and outs of redirecting for the initial navigation, though for user login I'd suggest that you either use a full screen popup or have a login control on your "normal" start page and toggle visibility based on your first run condition.
Add in class
private bool m_onNavigatedToCalled = false;
In ctor
this.LayoutUpdated += new EventHandler(MainPage_LayoutUpdated);
Then in code
void MainPage_LayoutUpdated(object sender, EventArgs e)
{
if (m_onNavigatedToCalled)
{
m_onNavigatedToCalled = false;
Dispatcher.BeginInvoke(() =>
{
if (NavigationService != null)
{
MessageBox.Show("Navigation not null?"); //always prompts
}
else
{
MessageBox.Show("Navigation service must be null?");
}
//StartApp(); do all stuff here to keep the ctor lightweight
}
);
}
}