How to set x button unclickable when show confirmation dialog? - c#

when I click x button app show confirmation dialog and if I click x button 2nd time, error occur because app can not create 2 dialogs at same time. Currently I can ignore 2nd x button click event by using a variable isBtnCloseClickedto save state of x and only create dialog when isBtnCloseClicked=false. But I don't want to register the state variable in every windows. Is there other way to do this using default UWP API ?, for example: disable x button when the dialog shows up.
Below is my code to handle x button event.
Windows.UI.Core.Preview.SystemNavigationManagerPreview.GetForCurrentView().CloseRequested +=
async (sender, args) =>
{
args.Handled = true;
ContentDialog locationPromptDialog = new ContentDialog
{
Title = "Do you want to exit?",
Content = "",
CloseButtonText = "No",
PrimaryButtonText = "Yes"
};
ContentDialogResult result = await locationPromptDialog.ShowAsync();
args.Handled = false;
if (result == ContentDialogResult.Primary)
{
App.Current.Exit();
}
};
Error when click x button 2nd time
System.Runtime.InteropServices.COMException
Message=An async operation was not properly started.
Only a single ContentDialog can be open at any time.
Source=Windows
StackTrace:
at Windows.UI.Xaml.Controls.ContentDialog.ShowAsync()
at CORsvr.MainPage.
Thanks

This should work for you.
Windows.UI.Core.Preview.SystemNavigationManagerPreview.GetForCurrentView().CloseRequested +=
async (sender, args) =>
{
args.Handled = true;
var messageDialog = new MessageDialog("Do you want to exit?");
messageDialog.Commands.Add(new UICommand(
"OK",
new UICommandInvokedHandler(this.OKCommandInvokedHandler)));
messageDialog.Commands.Add(new UICommand(
"Cancel",
new UICommandInvokedHandler(this.CancelCommandInvokedHandler)));
messageDialog.DefaultCommandIndex = 0;
messageDialog.CancelCommandIndex = 1;
await messageDialog.ShowAsync();
};
private void OKCommandInvokedHandler(IUICommand command)
{
}
private void CancelCommandInvokedHandler(IUICommand command)
{
}

Related

Why does my button not perform it's function until after other function is performed

I'm not sure which part of the code to show in order to explain my situation. But as stated in the title, after the WPF window has been initialized, and the createSheetbutton is clicked to simply display text for example. Nothing occurs until after another function has occurred.
The code below is the button click event which does nothing when called.
private void CreateSheetButton_Click(object sender, RoutedEventArgs e)
{
TaskDialog.Show("Me", "This is in the click event");
}
Here is the snippet of the code that has to be called before the click event fires. Not sure why this is happening.
private async void StartTask_Run()
{
var progress = new Progress<int>(value => progressBar.Value = value);
await Task.Run(() =>
{
DisableItems();
WorkSheetName = GetWorkSheetName();
StatusText("Connecting to document");
((IProgress<int>)progress).Report(5);
var sourceFile = ExcelSource.OpenExcelFile(FilePath);
StatusText("Getting Worksheet...");
((IProgress<int>)progress).Report(20);
var sourceWorkSheet = ExcelSource.GetWorkSheet(sourceFile.Item1, sourceFile.Item2, WorkSheetName); //instantiating the object.
StatusText("Getting cells count...");
((IProgress<int>)progress).Report(30);
var doc_Max = ExcelSource.GetDocRow_Col(sourceWorkSheet.Item1);
StatusText("Determining maximum cells with data...");
((IProgress<int>)progress).Report(40);
var maxRow_Col = ExcelSource.GetMaxRow_Col(sourceWorkSheet.Item1, doc_Max.Item1, doc_Max.Item2);
int maxRowCount = maxRow_Col.Item1;
int maxColCount = maxRow_Col.Item2;
StatusText("Compilling data...");
((IProgress<int>)progress).Report(60);
string[,] itemsArr = ExcelSource.GetItems(sourceWorkSheet.Item1, maxRow_Col);
StatusText("Processing information to view..");
((IProgress<int>)progress).Report(80);
Bindng2DArrayToListview2_Run_Search(listview, itemsArr, maxColCount);
EnableCreateSheetBtn();
((IProgress<int>)progress).Report(90);
StatusText("Tidying up...");
GarbageCollector(sourceWorkSheet.Item1, sourceWorkSheet.Item2, sourceWorkSheet.Item3, sourceWorkSheet.Item4);
EnableItems();
StatusText("Request Completed Successfully");
this.createSheetButton.Click += new RoutedEventHandler(CreateSheetButton_Click);
((IProgress<int>)progress).Report(100);
((IProgress<int>)progress).Report(0);
});
}
Any help will be appreciated.

NotifyIcon not showing context menu when app running background worker

My WPF application shows a window and when the user clicks a button, it begins to run its tasks and minimizes to a tray item in the notification area with a context menu where I would like the user to be able to cancel the operation.
The context menu worked before using a BackgroundWorker, however, cancellation did not. Since I've implemented a background worker,the context menu does not appear once the .runworkerasync() method has run.
My Notify Icon:
public NotifyIcon myNotifyIcon;
When my application runs I set it up like this:
private void setup_NotifyIcon()
{
myNotifyIcon = new NotifyIcon();
setTrayIcon();
myNotifyIcon.MouseDown += new MouseEventHandler(myNotifyIcon_MouseDown);
var menuItemCancel = new MenuItem("Cancel Parsing");
var contextMenu = new ContextMenu();
menuItemCancel.Click += new System.EventHandler(this.menuItemCancel_Click);
contextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { menuItemCancel });
myNotifyIcon.ContextMenu = contextMenu;
}
private void menuItemCancel_Click(object Sender, EventArgs e)
{
//do something
}
void myNotifyIcon_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
//do something
}
}
Then when the user clicks the button:
worker.RunWorkerAsync();
Why won't myNotifyIcon.MouseDown += new MouseEventHandler(myNotifyIcon_MouseDown); trigger the context menu?
The solution turned out to be a threading issue as suggested by Sebastian in the comments.
The key was to start the icon on another thread using Application.Run() and to make the icon visible within that code.
Once this was done, right-clicking on the icon worked, as did the cancellation functionality being handled.
private void setup_NotifyIcon()
{
Thread notifyThread = new Thread(
delegate ()
{
myNotifyIcon = new NotifyIcon();
setTrayIcon();
myNotifyIcon.MouseDown += new MouseEventHandler(myNotifyIcon_MouseDown);
mnuCancel = new MenuItem("Cancel Parsing");
menu = new ContextMenu();
mnuCancel.Click += new System.EventHandler(menuItemCancel_Click);
menu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { mnuCancel });
myNotifyIcon.ContextMenu = menu;
myNotifyIcon.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info; //Shows the info icon so the user doesn't thing there is an error.
myNotifyIcon.BalloonTipText = "The P6 Parser will minimize to the system tray while working.";
myNotifyIcon.BalloonTipTitle = "Processing...";
myNotifyIcon.Visible = true;
myNotifyIcon.ShowBalloonTip(500);
myNotifyIcon.Visible = true;
System.Windows.Forms.Application.Run();
});
notifyThread.Start();
}
in Program.cs change the Attribute [STAThread] to [MTAThread]

Custom Dialog result for the following custom message box

How can I implement custom dialog result for the following code, what all the changes I need to make in the following code to get the dialog result?
private void addButton(enumMessageButton MessageButton)
{
switch (MessageButton)
{
case enumMessageButton.OK:
{
//If type of enumButton is OK then we add OK button only.
Button btnOk = new Button(); //Create object of Button.
btnOk.Text = "OK"; //Here we set text of Button.
btnOk.DialogResult = DialogResult.OK; //Set DialogResult property of button.
btnOk.FlatStyle = FlatStyle.Popup; //Set flat appearence of button.
btnOk.FlatAppearance.BorderSize = 0;
btnOk.SetBounds(pnlShowMessage.ClientSize.Width - 80, 5, 75, 25); // Set bounds of button.
pnlShowMessage.Controls.Add(btnOk); //Finally Add button control on panel.
}
break;
case enumMessageButton.OKCancel:
{
Button btnOk = new Button();
btnOk.Text = "OK";
btnOk.DialogResult = DialogResult.OK;
btnOk.FlatStyle = FlatStyle.Popup;
btnOk.FlatAppearance.BorderSize = 0;
btnOk.SetBounds((pnlShowMessage.ClientSize.Width - 70), 5, 65, 25);
pnlShowMessage.Controls.Add(btnOk);
Button btnCancel = new Button();
btnCancel.Text = "Cancel";
btnCancel.DialogResult = DialogResult.Cancel;
btnCancel.FlatStyle = FlatStyle.Popup;
btnCancel.FlatAppearance.BorderSize = 0;
btnCancel.SetBounds((pnlShowMessage.ClientSize.Width - (btnOk.ClientSize.Width + 5 + 80)), 5, 75, 25);
pnlShowMessage.Controls.Add(btnCancel);
}
break;
}
}
internal static void ShowBox(string messageText, string messageTitle, enumMessageIcon messageIcon, enumMessageButton messageButton)
{
frmShowMessage frmMessage = new frmShowMessage();
frmMessage.setMessage(messageText);
frmMessage.Text = messageTitle;
frmMessage.addIconImage(messageIcon);
frmMessage.addButton(messageButton);
frmMessage.ShowDialog();
}
Main.cs
frmShowMessage.ShowBox("This is message box which represent message with title, custome button and custom icon.", "This is message title", enumMessageIcon.Question, enumMessageButton.OKCancel);
Now how do further I implement code to get dialog result?
Instead of
internal static void ShowBox(string messageText, string messageTitle, enumMessageIcon messageIcon, enumMessageButton messageButton)
{
frmShowMessage frmMessage = new frmShowMessage();
frmMessage.setMessage(messageText);
frmMessage.Text = messageTitle;
frmMessage.addIconImage(messageIcon);
frmMessage.addButton(messageButton);
frmMessage.ShowDialog();
}
try this
internal static DialogResult ShowBox(string messageText, string messageTitle, enumMessageIcon messageIcon, enumMessageButton messageButton)
{
frmShowMessage frmMessage = new frmShowMessage();
frmMessage.setMessage(messageText);
frmMessage.Text = messageTitle;
frmMessage.addIconImage(messageIcon);
frmMessage.addButton(messageButton);
return frmMessage.ShowDialog();
}
You have the formMessage object, adding controls and calling showDialog().
Note that when the ShowDialog returns, you still have the object frmMessage and
you can access the methods and properties on that object.
So when the corresponding buttons are clicked, you could set a property in your
fromMessage class on what button is pressed. Perhaps you have some additional fields that you can set.
After the showDialog returns, you can access those properties, perhaps construct your own DialogResult and return that result

Showing CustomDialog as modal dialog and get result (mahapps)

I have a class which creates SimpleDialog (now CustomDialog) with custom contents. So far I'm successful in showing it & closing it. But how to return its return to parent window? Just like how ShowDialog method does? The code so far is,
internal void fnShowDialog(MainWindow parent)
{
SimpleDialog dialog = new SimpleDialog();
StackPanel panel = new StackPanel();
Label block = new Label() { Content = "custom message" };
TextBlock block1 = new TextBlock() { Text = "custom message", FontSize = 22 };
Button button = new Button() { Content = "close" };
button.Click += (s, e) =>
{
parent.HideMetroDialogAsync((BaseMetroDialog)dialog);
};
panel.Children.Add(block);
panel.Children.Add(block1);
panel.Children.Add(button);
dialog.DialogBody = panel;
parent.ShowMetroDialogAsync((BaseMetroDialog)dialog);
}
I need to know the result of this dialog for further precessing accordingly.
I suggest you get the dialog's result in the Click event handler, the same place you call HideMetroDialogAsync.
Every Form has DialogResult property. You can set them on some event and then check the enum value of them in your dialog objects after closing the Form.
BaseMetroDialog could have DialogResult property which would be visible to parent.
This is a simple asynchronous process:
You should use await keyword to get the result:
var result = await parent.ShowMetroDialogAsync((BaseMetroDialog)dialog);
Don't forget to return result; at the end of the method.
Change your method definition to return this result like this:
internal async Task<MessageDialogResult> fnShowDialog(MainWindow parent)
This is the full method:
internal async Task<MessageDialogResult> fnShowDialog(MainWindow parent)
{
SimpleDialog dialog = new SimpleDialog();
StackPanel panel = new StackPanel();
Label block = new Label() { Content = "custom message" };
TextBlock block1 = new TextBlock() { Text = "custom message", FontSize = 22 };
Button button = new Button() { Content = "close" };
button.Click += (s, e) =>
{
parent.HideMetroDialogAsync((BaseMetroDialog)dialog);
};
panel.Children.Add(block);
panel.Children.Add(block1);
panel.Children.Add(button);
dialog.DialogBody = panel;
var result = await parent.ShowMetroDialogAsync((BaseMetroDialog)dialog);
return result;
}
You can use this method with an await like this:
var result = awiat fnShowDialog(parent);
if(result == ...)
{...}

How to show toast after performing some functionality in windows phone 8

I want to show something like toast after some functionality performed. i-e I have a save button and I want that when it pressed then a toast should be shown with the text Record Saved etc. I read posts that show toasts are only for back-ground agents. I know someone will give me good guidance. please specify some code.
Thanks
You can use the Toast Prompt from the Coding4Fun Toolkit to perform a toast notification via code. After referencing the toolkit (ideally via NuGet) you can use it like this:
ToastPrompt toast = new ToastPrompt();
toast.Title = "Your app title";
toast.Message = "Record saved.";
toast.TextOrientation = Orientation.Horizontal;
toast.MillisecondsUntilHidden = 2000;
toast.ImageSource = new BitmapImage(new Uri("ApplicationIcon.png", UriKind.RelativeOrAbsolute));
toast.Show();
I prefer ProgressIndicator in my apps but you can use Popup or ToastPrompt.
Sample project.
// popup member
private Popup popup;
// creates popup
private Popup CreatePopup()
{
// text
TextBlock tb = new TextBlock();
tb.Foreground = (Brush)this.Resources["PhoneForegroundBrush"];
tb.FontSize = (double)this.Resources["PhoneFontSizeMedium"];
tb.Margin = new Thickness(24, 32, 24, 12);
tb.Text = "Custom toast message";
// grid wrapper
Grid grid = new Grid();
grid.Background = (Brush)this.Resources["PhoneAccentBrush"];
grid.Children.Add(tb);
grid.Width = this.ActualWidth;
// popup
Popup popup = new Popup();
popup.Child = grid;
return popup;
}
// hides popup
private void HidePopup()
{
SystemTray.BackgroundColor = (Color)this.Resources["PhoneBackgroundColor"];
this.popup.IsOpen = false;
}
// shows popup
private void ShowPopup()
{
SystemTray.BackgroundColor = (Color)this.Resources["PhoneAccentColor"];
if (this.popup == null)
{
this.popup = this.CreatePopup();
}
this.popup.IsOpen = true;
}
// shows and hides popup with a delay
private async void ButtonClick(object sender, RoutedEventArgs e)
{
this.ShowPopup();
await Task.Delay(2000);
this.HidePopup();
}
using Windows.UI.Notifications;
var toastXmlContent = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
var txtNodes = toastXmlContent.GetElementsByTagName("text");
txtNodes[0].AppendChild(toastXmlContent.CreateTextNode("First Line"));
txtNodes[1].AppendChild(toastXmlContent.CreateTextNode("Second Line" ));
var toast = new ToastNotification(toastXmlContent);
var toastNotifier = ToastNotificationManager.CreateToastNotifier();
toastNotifier.Show(toast);

Categories