Showing CustomDialog as modal dialog and get result (mahapps) - c#

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 == ...)
{...}

Related

UWP C# Menuflyout Unable To Display Item Properly During 1st Click

I am having an issue with my code to add button from json where the first attempt i click add button, the menuflyout won't have any respond but second click attempt then it will work properly.
Can advise did i do anything wrong? Thanks.
private async void AddButton_Click(object sender, RoutedEventArgs e)
{
List<ClientList> clientLists;
var jsonSerializer = new DataContractJsonSerializer(typeof(List<ClientList>));
var myStream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(CLIENTSLIST);
clientLists = (List<ClientList>)jsonSerializer.ReadObject(myStream);
var menuFlyout = new MenuFlyout();
int isEmpty = myGrid.Children.Count;
if (isEmpty == 0)
{
foreach (var device in clientLists)
{
var menuFlyoutItem = new MenuFlyoutItem() { Name = device.clientname, Text = device.clientname };
menuFlyoutItem.Tag = device.clientaddress;
menuFlyoutItem.Click += AddMenuFlyoutItem_Click;
menuFlyout.Items.Add(menuFlyoutItem);
}
}else
{
foreach (var device in clientLists)
{
bool toAddButton = true;
foreach (Button btn in myGrid.Children.OfType<Button>())
{
if (btn.Content.ToString() == device.clientname)
{
toAddButton = false;
}
}
if (toAddButton)
{
var menuFlyoutItem = new MenuFlyoutItem() { Name = device.clientname, Text = device.clientname };
menuFlyoutItem.Tag = device.clientaddress;
menuFlyoutItem.Click += AddMenuFlyoutItem_Click;
menuFlyout.Items.Add(menuFlyoutItem);
}
}
}
AddButton.Flyout = menuFlyout;
}
The problem is you are loading the data asynchronously here:
var myStream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(CLIENTSLIST);
When this happens, UI continues executing the Click event, so the button is clicked (and Flyout is null the first time) and Flyout will never display. You should rather load the Flyout before that - either when the page loads or when the data source changes, so that when the user clicks, the flyout is already there. Doing loading in Click is simply too late, if you need an asynchronous operation to finish.
Alternatively you could set the flyout right at the start:
private async void AddButton_Click(object sender, RoutedEventArgs e)
{
var menuFlyout = new MenuFlyout();
AddButton.Flyout = menuFlyout;
List<ClientList> clientLists;
var jsonSerializer = new DataContractJsonSerializer(typeof(List<ClientList>));
var myStream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(CLIENTSLIST);
clientLists = (List<ClientList>)jsonSerializer.ReadObject(myStream);
int isEmpty = myGrid.Children.Count;
if (isEmpty == 0)
{
foreach (var device in clientLists)
{
var menuFlyoutItem = new MenuFlyoutItem() { Name = device.clientname, Text = device.clientname };
menuFlyoutItem.Tag = device.clientaddress;
menuFlyoutItem.Click += AddMenuFlyoutItem_Click;
menuFlyout.Items.Add(menuFlyoutItem);
}
}else
{
foreach (var device in clientLists)
{
bool toAddButton = true;
foreach (Button btn in myGrid.Children.OfType<Button>())
{
if (btn.Content.ToString() == device.clientname)
{
toAddButton = false;
}
}
if (toAddButton)
{
var menuFlyoutItem = new MenuFlyoutItem() { Name = device.clientname, Text = device.clientname };
menuFlyoutItem.Tag = device.clientaddress;
menuFlyoutItem.Click += AddMenuFlyoutItem_Click;
menuFlyout.Items.Add(menuFlyoutItem);
}
}
}
}
This way, the flyout will appear, but will be empty until the asynchronous loading finishes and the items are actually added. Here you are just reading a file, so it should be barely noticeable. Although not as clean as pre-loading the flyout, it should get the job done too.

How to set x button unclickable when show confirmation dialog?

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)
{
}

Set Back Button Title on Xamarin Forms C#

im quite new to c# and Xamarin and I've just encountered a problem. I can't seem to be able to set the back button title on a navigation page. Ive tried using the static SetBackButtonTitle method but it does not seem to set the back button to the title I want which is
'Test' but instead its giving me the 'default' title which is "Back".
// The root page of your application
var content = new ContentPage();
var CompanyName = new Label();
CompanyName.HorizontalTextAlignment = TextAlignment.Center;
CompanyName.Text = "Test";
var NextPage = new Button();
NextPage.Text = "Next Page";
NextPage.Font = Font.SystemFontOfSize(NamedSize.Large);
NextPage.BorderWidth = 1;
NextPage.HorizontalOptions = LayoutOptions.Center;
NextPage.VerticalOptions = LayoutOptions.CenterAndExpand;
var layout = new StackLayout();
layout.VerticalOptions = LayoutOptions.CenterAndExpand;
layout.Children.Add(CompanyName);
layout.Children.Add(NextPage);
content.Content = layout;
var content2 = new ContentPage();
var navigation = new NavigationPage(content);
NavigationPage.SetHasBackButton(navigation,true);
NavigationPage.SetBackButtonTitle(navigation,"Test");
NextPage.Clicked += NextPageClicked;
async void NextPageClicked(object sender, EventArgs e)
{
await navigation.PushAsync(content2);
}
MainPage = navigation;
}
If you want to change the back button's title(at the left in the navigation bar) in the second page, you should call the method SetBackButtonTitle with first page as parameter. So please modify NavigationPage.SetBackButtonTitle(navigation,"Test"); to NavigationPage.SetBackButtonTitle(content,"Test");
For those who use Xamarin.Forms WPF if you want to change back button title you can do this:
protected override void OnDisappearing()
{
base.OnDisappearing();
Title = "";
}
protected override void OnAppearing()
{
base.OnAppearing();
Title = "MyTitle";
}

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

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