Windows Phone: How to add custom confirmation dialog in OnBackKeyPress - c#

I am going to implement custom confirmation dialog in OnBackKeyPress method. It is easy to do with native message box:
protected override void OnBackKeyPress(CancelEventArgs e)
{
base.OnBackKeyPress(e);
MessageBoxResult result = MessageBox.Show("Text");
if(result==MessageBoxResult.OK)
{
e.Cancel = true;
}
}
It works, but I dislike limitation with two buttons so I am looking for something else.
I have checked WPtoolkit:
private bool m_cansel = false;
protected override void OnBackKeyPress(CancelEventArgs e)
{
base.OnBackKeyPress(e);
if (!m_cansel)
{
e.Cancel = true;
m_cansel = true;
var messageBox = new CustomMessageBox
{
Title = "Title",
Message = "Message",
RightButtonContent = "aas",
IsLeftButtonEnabled = false,
};
messageBox.Dismissed += (sender, args) =>
{
};
messageBox.Show();
}
}
And Coding4Fun:
private bool m_cansel = false;
protected override void OnBackKeyPress(CancelEventArgs e)
{
base.OnBackKeyPress(e);
if (!m_cansel)
{
e.Cancel = true;
m_cansel = true;
var messageBox = new MessagePrompt
{
Title = "Title",
Message = "Message",
};
messageBox.Completed += (sender, args) =>
{
//throw new NotImplementedException();
};
messageBox.Show();
}
Both looks good, but don't work in OnBackKeyPress method (show and immediately disappear without any my action).
Moreover, I've tried XNA:
private bool m_cansel = false;
protected override void OnBackKeyPress(CancelEventArgs e)
{
base.OnBackKeyPress(e);
if (!m_cansel)
{
e.Cancel = true;
m_cansel = true;
Guide.BeginShowMessageBox("Version of Windows", "Pick a version of Windows.",
new List<string> {"Vista", "Seven"}, 0, MessageBoxIcon.Error,
asyncResult =>
{
int? returned = Guide.EndShowMessageBox(asyncResult);
}, null);
}
}
It works as I expected (has customs in OnBackKeyPress method), but I don't sure that using XNA inside Silverlight app is good practice.
So, I am looking a way to use WPtoolkit or Coding4Fun windows inside OnBackKeyPress method or any explanation about using XNA inside Silverlight app (any recomendation or info about approval such kind app by store).

Just use the dispatcher to delay the messagebox until you get out of the OnBackKeyPress event, and it should work:
private bool m_cansel = false;
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
base.OnBackKeyPress(e);
if (!m_cansel)
{
e.Cancel = true;
m_cansel = true;
var messageBox = new CustomMessageBox
{
Title = "Title",
Message = "Message",
RightButtonContent = "aas",
IsLeftButtonEnabled = false,
};
messageBox.Dismissed += (sender, args) =>
{
};
Dispatcher.BeginInvoke(messageBox.Show);
}
}
Alternatively, you can use the BackKeyPress event instead of overriding the OnBackKeyPress method. This way, you don't need to use the dispatcher:
privatevoid Page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
{
if (!m_cansel)
{
e.Cancel = true;
m_cansel = true;
var messageBox = new CustomMessageBox
{
Title = "Title",
Message = "Message",
RightButtonContent = "aas",
IsLeftButtonEnabled = false,
};
messageBox.Dismissed += (s, args) =>
{
};
messageBox.Show();
}
}
And in the XAML:
BackKeyPress="Page_BackKeyPress"

Related

C# Enable/disable user form when process exited event fires not working

I have this code:
private void btnAddDataToCSV_Click(object sender, EventArgs e)
{
var myProcess = new Process();
this.Enabled = false;
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(Excel_Exit);
myProcess.StartInfo.FileName = "D:\\MyCsvFile.csv";
myProcess.Start();
}
public void Excel_Exit(object sender, System.EventArgs e)
{
MessageBox.Show("Success!!");
this.Enabled = true;
}
The code works as far as graying out all the buttons on my C# user form and opening the csv file in Excel. When I close Excel the exit event fires displaying a message "Success!!" But it doesn't re-enable the buttons after closing Excel.
I am getting the error
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll
on the this.Enabled = true; line.
As you can see from my comments below. I have now come to to realization that I cannot figure out how to disable even a single button.
private void btnAddDataToCSV_Click(object sender, EventArgs e)
{
var myProcess = new Process();
button1.Enabled = false;
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(Excel_Exit);
myProcess.StartInfo.FileName = "D:\\MyCsvFile.csv";
myProcess.Start();
}
public void Excel_Exit(object sender, System.EventArgs e)
{
button1.Enabled = true;
}
The event is firing because the code below works... (displays success!!)
private void btnAddDataToCSV_Click(object sender, EventArgs e)
{
var myProcess = new Process();
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(Excel_Exit);
myProcess.StartInfo.FileName = "D:\\MyCsvFile.csv";
myProcess.Start();
}
public void Excel_Exit(object sender, System.EventArgs e)
{
MessageBox.Show("Success!!");
}
Any help would be greatly appreciated.
i have added 2 more controls to the form, and set it to disabled on opening of excel file.
private void btnAddDataToCSV_Click(object sender, EventArgs e)
{
var myProcess = new Process();
AddtoCsv.Enabled = false;
textBox1.Enabled = false;
checkBox1.Enabled = false;
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(Excel_Exit);
myProcess.StartInfo.FileName = "E:\\MyCsvFile.csv";
myProcess.Start();
}
after that, fetched all the controls inside our form and pass it to SetButtonState method.
public void Excel_Exit(object sender, System.EventArgs e)
{
// Set Button Enable State True
var controls = this.Controls.Cast<Control>();
foreach (Control ctrl in controls)
{
SetButtonState(ctrl);
}
}
SetButtonState wil make call to invoke method of passed control and then we are able to make changes onto control.
private delegate void SafeCallDelegate(Control control);
private void SetButtonState(Control control)
{
// check if current thread is same which have created this control
if (control.InvokeRequired)
{
SafeCallDelegate d = new SafeCallDelegate(SetButtonState);
control.Invoke(d, control);
}
else
{
control.Enabled = true;
}
}
Replace this.Enabled = false; with AddtoCsv.Enabled = false;
private void btnAddDataToCSV_Click(object sender, EventArgs e)
{
var myProcess = new Process();
AddtoCsv.Enabled = false;
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(Excel_Exit);
myProcess.StartInfo.FileName = "E:\\MyCsvFile.csv";
myProcess.Start();
}
Just call SetButtonStatemethod inside your Excel_Exit method, and do not forget to declare the delegate.
public void Excel_Exit(object sender, System.EventArgs e)
{
// Set Button Enable State True
SetButtonState();
}
private delegate void SafeCallDelegate();
private void SetButtonState()
{
// check if current thread is same which have created this control
if (AddtoCsv.InvokeRequired)
{
SafeCallDelegate d = new SafeCallDelegate(SetButtonState);
AddtoCsv.Invoke(d);
}
else
{
AddtoCsv.Enabled = true;
}
}
Ok... I couldn't get the entire form to disable. But based on other stuff I have found, I created a "panel" and put all my buttons inside the panel and was able to enable the entire panel.
So the solution below works. Special thanks to Paramjot Singh who posted the other solution which works great for a single button, I don't know if I would have figured this out without his help!!
private void btnAddDataToCSV_Click(object sender, EventArgs e)
{
var myProcess = new Process();
panel1.Enabled = false;
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(Excel_Exit);
myProcess.StartInfo.FileName = "E:\\MyCsvFile.csv";
myProcess.Start();
}
public void Excel_Exit(object sender, System.EventArgs e)
{
// Set Button Enable State True
SetButtonState();
}
private delegate void SafeCallDelegate();
private void SetButtonState()
{
// check if current thread is same which have created this control
if (panel1.InvokeRequired)
{
SafeCallDelegate d = new SafeCallDelegate(SetButtonState);
panel1.Invoke(d);
}
else
{
panel1.Enabled = true;
}
}

Modern UI Dialog result issues

I am working with Modern UI and attempting to make a dialog box that asks a question and then waits for a response. I can do this with messagebox but though I would try using modern UI. I am unsure of how to get the button clicked value.
if (testapp.linkvalue != "NULL")
{
var v = new ModernDialog
{
Title = "my test",
Content = "pewpew lazers rule. If you agree click ok"
};
v.Buttons = new Button[] { v.OkButton, v.CancelButton };
var r = v.ShowDialog();
if (????????????????)
{
MessageBox.Show("ok was clicked");
}
else
{
MessageBox.Show("cancel was clicked");
}
}
if (testapp.linkvalue != "NULL")
{
var v = new ModernDialog
{
Title = "my test",
Content = "pewpew lazers rule. If you agree click ok"
};
v.OkButton.Click += new RoutedEventHandler(OkButton_Click);
v.Buttons = new Button[] { v.OkButton, v.CancelButton };
var r = v.ShowDialog();
}
//And Then Create OkButtonClick
private void OkButton_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("ok was clicked");
}
private void CommonDialog_Click(object sender, RoutedEventArgs e)
{
var dlg = new ModernDialog {
Title = "Common dialog",
Content = new LoremIpsum()
};
dlg.Buttons = new Button[] { dlg.OkButton, dlg.CancelButton};
dlg.ShowDialog();
this.dialogResult.Text = dlg.DialogResult.HasValue ? dlg.DialogResult.ToString() : "<null>";
this.dialogMessageBoxResult.Text = dlg.MessageBoxResult.ToString();
}
It might be another solution using extension method.
var r = v.ShowDialogOKCancel();
if (r==MessageBoxResult.OK)
{
MessageBox.Show("ok was clicked");
}
else
{
MessageBox.Show("cancel was clicked");
}
static class ModernDialogExtension
{
static MessageBoxResult result;
public static MessageBoxResult ShowDialogOKCancel(this FirstFloor.ModernUI.Windows.Controls.ModernDialog modernDialog)
{
result = MessageBoxResult.Cancel;
modernDialog.OkButton.Click += new RoutedEventHandler(OkButton_Click);
modernDialog.Buttons = new Button[] { modernDialog.OkButton, modernDialog.CloseButton };
modernDialog.ShowDialog();
return result;
}
private static void OkButton_Click(object sender, RoutedEventArgs e)
{
result = MessageBoxResult.OK;
}
}

Change the mouse drag cursor in WPF

I have to disply the number of dragged files count on mouse cursor while dragging document from file system to my form.
I have done the following code, but I can not change the drag cursor. Please let me know the best way to do this
private void tbDisplayFileContents_PreviewDragOver(object sender, DragEventArgs args)
{
if (IsSingleFile(args) != null)
{
tbDisplayFileContents_PreviewDrop(sender, args);
}
else
{
// args.Effects = DragDropEffects.None;
}
Mouse.SetCursor(Cursors.Hand);
Icon ico = new Icon(string.Concat("1365516094_10371.ico"));
tbDisplayFileContents.Cursor = GenerateCursor.CreateCursor(ico, true, new System.Drawing.Color());
args.Handled = true;
}
private void tbDisplayFileContents_PreviewDrop(object sender, DragEventArgs args)
{
args.Handled = true;
string files = string.Empty;
string[] fileName = IsSingleFile(args);
if (fileName == null) return;
isDrag = true;
DoEvents();
for (int i = 0; i < fileName.Length; i++)
{
if (i == 0)
{
files = string.Concat("1] ", fileName[i]);
}
else
{
int j = i + 1;
files = string.Concat(files, Environment.NewLine, j, "] ", fileName[i]);
}
}
lblfileName.Content = files;
}
private string[] IsSingleFile(DragEventArgs args)
{
if (args.Data.GetDataPresent(DataFormats.FileDrop, true))
{
string[] fileNames = args.Data.GetData(DataFormats.FileDrop, true) as string[];
if (fileNames.Length != 0)
{
if (File.Exists(fileNames[0]))
{
// At this point we know there is a single file.
return fileNames;
}
}
}
return null;
}
#endregion
#region -------Events--------
private void btnClear_Click(object sender, RoutedEventArgs e)
{
lblfileName.Content = string.Empty;
}
#endregion
private void tbDisplayFileContents_PreviewDragEnter(object sender, DragEventArgs e)
{
e.Effects = DragDropEffects.None;
}
public static void DoEvents()
{
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background,
new Action(delegate
{
Icon ico = new Icon(string.Concat("1365516094_10371.ico"));
Mouse.OverrideCursor = GenerateCursor.CreateCursor(ico, true, new System.Drawing.Color());
}));
}
I have used GiveFeedBack event as follows
private void tbDisplayFileContents_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
if (e.Effects == DragDropEffects.Copy)
{
e.UseDefaultCursors = false;
// Mouse.SetCursor(Cursors.Hand);
Icon ico = new Icon(string.Concat("1365516094_10371.ico"));
//Mouse.Cursor = GenerateCursor.CreateCursor(ico, true, new System.Drawing.Color());
Mouse.SetCursor(GenerateCursor.CreateCursor(ico, true, new System.Drawing.Color()));
}
else
e.UseDefaultCursors = true;
e.Handled = true;
}
It is working for form to form dragging but it is not working for the contents(file) which is dragged from outside form e.g files from Desktop.
I miss the GiveFeedback event in your code, which is used to modify the Mouse cursor while drag and drop operations.

C# UserControl Not and Yes with Text

The Default is No Checkbox
When I run the program and Click the Yes Checkbox the program overflowed
private void checkEdit1_Click(object sender, EventArgs e)
{
checkEdit2.Checked = false;
textEdit1.Enabled = true;
answered = true;
optional = textEdit1.Text;
if (!checkEdit1.Checked)
{
checkEdit1.Checked = true;
checkEdit2.Checked = false;
textEdit1.Enabled = true;
optional = textEdit1.Text;
}
}
private void checkEdit2_Click(object sender, EventArgs e)
{
checkEdit1.Checked = false;
textEdit1.Enabled = false;
answered = false;
if (!checkEdit2.Checked)
{
checkEdit2.Checked = true;
checkEdit1.Checked = false;
textEdit1.Enabled = false;
answered = false;
}
}
What you think is the error ?
Instead of the Click event you should use the CheckedChanged event in this way:
checkEdit1.CheckedChenged += new EventHandler(checkEdit1_CheckedChanged);
checkEdit2.CheckedChenged += new EventHandler(checkEdit2_CheckedChanged);
private void checkEdit1_CheckedChanged(object sender, EventArgs e)
{
if(checkEdit1.Checked == checkEdit2.Checked)
checkEdit2.Checked = !checkEdit.Checked;
}
private void checkEdit2_CheckedChanged(object sender, EventArgs e)
{
if(checkEdit1.Checked == checkEdit2.Checked)
checkEdit2.Checked = !checkEdit.Checked;
}
But the best way in this case is to use a group of radio buttons.
Assuming that those methods are wired up to checkEdit1 and checkEdit2 I would advise that you don't make a change to checkEdit1 in checkEdit1_Click as it has already changed - only modify the state of the alternate.
However, when you modify the state of the other, unless you're careful, you're going to get called back. Eventually the computer gives up -- the overflow!
As mentioned in a comment by #Cyborgx37, radio buttons are the better UX choice here!
A possible solution, bind a single method to the OnClick to BOTH checkboxes:
private bool internallyUpdating = false;
private void CheckboxClick(object sender, EventArgs e)
{
if ( !internallyUpdating )
{
// Prevent subsequent changes
internallyUpdating = true;
// Exchange 'checked' state
if ( sender == checkEdit1 )
{
checkEdit2.Checked = !checkEdit2.Checked;
}
else // if (sender == checkEdit2)
{
checkEdit1.Checked = !checkEdit1.Checked;
}
// other logic here..
// restore 'on change' functionality.
internallyUpdating = false;
}

How to prevent my textbox from clearing text on postback.

I have a pretty interesting dilemma that is giving me a hurricane of a headache. I've seen a similar question asked here, but the user posted no code, so it was unresolved. This is a asp.net, sql server, and c# app.
In my application, I use JavaScript to display dummy data in a TextBox to entertain the user while a long process is running. (please note, this is a project, not a professional app).
The problem is, once the app is done executing, the app (I believe) refreshes the page and clears the TextBox. I want to prevent this from happening and continue to display the text after the program is completed.
My question is, where in the following code is the page being refreshed? How can I re-code it to prevent the text from being cleared?
I know there is no issue with the JavaScript or the .aspx page. I have not set or programmed any property to clear the text. If anyone could shed light on the issue, I would greatly appreciate it. If you need more code from me please let me know. I will be very active on this page until it is resolved. Thanks again!
public partial class SendOrders : System.Web.UI.Page
{
protected enum EDIType
{
Notes,
Details
}
protected static string NextBatchNum = "1";
protected static string FileNamePrefix = "";
protected static string OverBatchLimitStr = "Batch file limit has been reached. No more batches can be processed today.";
protected void Page_Load(object sender, EventArgs e)
{
Initialize();
}
protected void Page_PreRender(object sender, EventArgs e)
{ }
protected void btnExit_Click(object sender, EventArgs e)
{
System.Diagnostics.Process.GetCurrentProcess().Kill();
}
protected void Button_Click(object sender, EventArgs e)
{
PutFTPButton.Enabled = false;
Thread.Sleep(3000);
Button btn = (Button)sender;
KaplanFTP.BatchFiles bf = new KaplanFTP.BatchFiles();
KaplanFTP.Transmit transmit = new KaplanFTP.Transmit();
if (btn.ID == PutFTPButton.ID)
{
DirectoryInfo dir = new DirectoryInfo(#"C:\Kaplan");
FileInfo[] BatchFiles = bf.GetBatchFiles(dir);
bool result = transmit.UploadBatchFilesToFTP(BatchFiles);
if (!result)
{
ErrorLabel.Text += KaplanFTP.errorMsg;
return;
}
bf.InsertBatchDataIntoDatabase("CTL");
bf.InsertBatchDataIntoDatabase("HDR");
bf.InsertBatchDataIntoDatabase("DET");
bf.InsertBatchDataIntoDatabase("NTS");
List<FileInfo> allfiles = BatchFiles.ToList<FileInfo>();
allfiles.AddRange(dir.GetFiles("*.txt"));
bf.MoveFiles(allfiles);
foreach (string order in bf.OrdersSent)
{
OrdersSentDiv.Controls.Add(new LiteralControl(order + "<br />"));
}
btnExit.Visible = true;
OrdersSentDiv.Visible = true;
OrdersInfoDiv.Visible = false;
SuccessLabel.Visible = true;
NoBatchesToProcessLbl.Visible = true;
BatchesToProcessLbl.Visible = false;
PutFTPButton.Enabled = false;
BatchesCreatedLbl.Text = int.Parse(NextBatchNum).ToString();
Thread.Sleep(20000);
if (KaplanFTP.errorMsg.Length != 0)
{
ErrorLabel.Visible = false;
SuccessLabel.Visible = true;
ErrorLabel.Text = KaplanFTP.errorMsg;
}
}
}
private void Initialize()
{
KaplanFTP.BatchFiles bf = new KaplanFTP.BatchFiles();
if (!IsPostBack)
{
FileNamePrefix = bf.FileNamePrefix;
NextBatchNum = bf.NextBatchNum;
BatchesCreatedLbl.Text = (int.Parse(NextBatchNum) - 1).ToString();
if (bf.CheckLocalForNewBatch() == true)
{
NoBatchesToProcessLbl.Visible = false;
BatchesToProcessLbl.Visible = true;
if (int.Parse(NextBatchNum) >= 50)
{
ErrorLabel.Text += ErrorLabel.Text + OverBatchLimitStr;
ErrorLabel.Visible = true;
PutFTPButton.Enabled = false;
}
else
{
bf.ReadyFilesForTransmission();
ErrorLabel.Visible = false;
PutFTPButton.Enabled = true;
List<string[]> detStream = bf.GetBatchStream("DET");
List<string[]> hdrStream = bf.GetBatchStream("HDR");
OrdersInfoDiv.Visible = true;
DataTable dt = new DataTable();
dt.Columns.Add("ORDER NUMBER");
dt.Columns.Add("LINE NUMBER");
dt.Columns.Add("ITEM NUMBER/ISBN");
dt.Columns.Add("DESCRIPTION");
dt.Columns.Add("QUANTITY");
dt.Columns.Add("SHIPPING");
Dictionary<string, string> orderShip = new Dictionary<string, string>();
foreach (string[] hdrItems in hdrStream)
{
orderShip.Add(hdrItems[0], hdrItems[2]);
}
foreach (string[] detItems in detStream)
{
List<string> detLineList = new List<string>(detItems);
detLineList.Add(orderShip[detItems[0]]);
detLineList.RemoveAt(13);
detLineList.RemoveAt(12);
detLineList.RemoveAt(11);
detLineList.RemoveAt(10);
detLineList.RemoveAt(9);
detLineList.RemoveAt(8);
detLineList.RemoveAt(7);
detLineList.RemoveAt(4);
detLineList.RemoveAt(2);
detLineList[1] = detLineList[1].TrimStart('0');
detLineList[4] = detLineList[4].TrimStart('0');
dt.Rows.Add(detLineList.ToArray());
}
BatchDetails.DataSource = dt;
BatchDetails.DataBind();
}
}
else
{
NoBatchesToProcessLbl.Visible = true;
BatchesToProcessLbl.Visible = false;
PutFTPButton.Enabled = false;
}
}
}
}
Yes. You will have to determine the state of your calculation and populate the control inside Page_Load in the case where IsPostBack is true:
protected void Page_Load(object sender, EventArgs e) {
if (IsPostBack) {
// re-populate javascript-fill UI
} else {
}
Initialize();
}
You can probably also move Initialize() into the else clause as well.
Since you are handling the button click server side (I'm assuming the problem is happening once the user clicks the button?) there has to be a postback to handle it.
You could try putting your button and label into an updatepanel control - it uses AJAX to refresh its contents.
See this page for more information on updatepanels.

Categories

Resources