Set a default font for whole iOS app in Xamarin.iOS? - c#

I can enable fonts for Label, entry, etc(Xamarin.Forms UI fields) like this...
<Style TargetType="Label">
<Setter Property="FontFamily">
<Setter.Value>
<OnPlatform x:TypeArguments="x:String">
<On Platform="iOS" Value="Montserrat_Regular" />
<On Platform="Android" Value="Montserrat_Regular.ttf#Montserrat_Regular" />
</OnPlatform>
</Setter.Value>
</Setter>
</Style>
But it doesn't apply font for title & content of dialog boxes, list in pickers n many more places like that(Internal iOS UI fields).
I override the default font of android to achieve the above issue, but the problem is with iOS, I can't find any solution for it in C#.
There are many solutions present in objective-c & swift.
Objective-c Solution
Swift 5 solution
Another Solution
Can someone help me convert these codes or provide any other solution?
EDIT -
Dialog Boxes are Device Specific, Xamarin.Forms code won't work individually on it.
iOS Dialog box -
Device.BeginInvokeOnMainThread( () =>
{
UIAlertController alert = UIAlertController.Create(title, message, UIAlertControllerStyle.Alert);
alert.AddAction(UIAlertAction.Create(cancel, UIAlertActionStyle.Cancel, a => task.SetResult(false)));
alert.AddAction(UIAlertAction.Create(ok, UIAlertActionStyle.Default, a => task.SetResult(true)));
UIViewController vc = GetViewController(UIApplication.SharedApplication.KeyWindow.RootViewController);
if (TargetIdiom.Tablet == Device.Idiom)
{
vc.ModalPresentationStyle = UIModalPresentationStyle.Popover;
}
vc.PresentModalViewController(alert, true);
});
Android Dialog box with fix for font -
Device.BeginInvokeOnMainThread( () =>
{
AlertDialog dialog = new AlertDialog.Builder(Forms.Context, Resource.Style.Base_Animation_AppCompat_Tooltip).SetTitle(title).SetMessage(content).SetPositiveButton(ok, delegate { task.SetResult(true); })
.SetNegativeButton(cancel, delegate { task.SetResult(false); }).Show();
TextView textView = (TextView)dialog.FindViewById(Android.Resource.Id.Message);
textView.SetTypeface(Typeface.CreateFromAsset(Forms.Context.Assets, "Montserrat_Regular.ttf"), TypefaceStyle.Normal);
var _buttonOK = (Button)dialog.FindViewById(Android.Resource.Id.Button1);
_buttonOK.SetTypeface(Typeface.CreateFromAsset(Forms.Context.Assets, "Montserrat_Regular.ttf"), TypefaceStyle.Normal);
var _buttonCancel = (Button)dialog.FindViewById(Android.Resource.Id.Button2);
_buttonCancel.SetTypeface(Typeface.CreateFromAsset(Forms.Context.Assets, "Montserrat_Regular.ttf"), TypefaceStyle.Normal);
});

You can creat a Custom Label Renderer to achieve that.
Create the CustomLabelRenderer in iOS solution:
[assembly: ExportRenderer(typeof(Label), typeof(CustomLabelRenderer))]
namespace XamarinTableView.iOS
{
public class CustomLabelRenderer: LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
Control.Font = UIFont.FromName("Montserrat-Regular", (nfloat)Element.FontSize);
}
}
}
You will see the typeof(Label), it means will work for all the Label of Xamarin Forms in iOS device.
==============================Update=================================
I have checked in local site and make it works for UILable. You need to add Montserrat-Regular.ttf file inside the iOS solution correctly.
For example:
And also need to add this .ttf in info.plist as follows:
<key>UIAppFonts</key>
<array>
<string>Montserrat-Regular.ttf</string>
</array>
Then the renderer code will work.
In addition, you can use typeof(CustomLabel) to use the special effect for special Label.
=================================Update #2================================
If need to works for UIAlertController ,have a try with follow ways. However, there is no way to modify the font of Button in iOS, it only works for Title and Message.
Device.BeginInvokeOnMainThread(() =>
{
UIAlertController alert = UIAlertController.Create(title, message, UIAlertControllerStyle.Alert);
var titleAttributedString = new NSAttributedString(title,
new CTStringAttributes()
{
ForegroundColorFromContext = true,
Font = new CTFont("Montserrat-Regular", 24)
});
alert.SetValueForKey(titleAttributedString, new NSString("attributedTitle"));
var messageAttributedString = new NSAttributedString(message,
new CTStringAttributes()
{
ForegroundColorFromContext = true,
Font = new CTFont("Montserrat-Regular", 24)
});
alert.SetValueForKey(messageAttributedString, new NSString("attributedMessage"));
UIAlertAction cancleAction = UIAlertAction.Create("Cancle", UIAlertActionStyle.Cancel, a => Console.WriteLine("cancle"));
alert.AddAction(cancleAction);
UIAlertAction okAction = UIAlertAction.Create("OK", UIAlertActionStyle.Cancel, a => Console.WriteLine("OK"));
alert.AddAction(okAction);
UIViewController vc = GetViewController(UIApplication.SharedApplication.KeyWindow.RootViewController);
if (TargetIdiom.Tablet == Device.Idiom)
{
vc.ModalPresentationStyle = UIModalPresentationStyle.Popover;
}
vc.PresentModalViewController(alert, true);
});
The effect:

you can't override default font, you need to set font on individual components for now, I'll let you know if i found any better solution

Related

Windows Lock Screen, add Text programmatically

I want to display custom text or control on the Windows 10 Lockscreen, when I click on a button. I tried it with an UWP Application.
My goal is something like this:
And the Code I tried:
ToastContent content = new ToastContent()
{
//Duration = ToastDuration.Long,
Scenario = ToastScenario.Reminder,
Visual = new ToastVisual()
{
BindingGeneric = new ToastBindingGeneric()
{
Attribution = new ToastGenericAttributionText()
{
Text = "Hello World"
}
}
},
Actions = new ToastActionsCustom()
{
Buttons = {
new ToastButton ("mycontent", "myargs")
}
}
};
var notification = new ToastNotification(content.GetXml());
ToastNotificationManager.CreateToastNotifier().Show(notification);
Also I saw this post and tried it of course, but it wasnt helpfull: Windows Lock Screen display text programmatically C#
Maybe you could help me to achive my goald
I thank you in advance
The screenshot you post above is smtc that used to show current playing music, for enable it you need to enable the app Background Media Playback, but it only use to show the media info, it can't use to share custom info like you mentioned scenario.
For your scenario, the better way is register your app LockScreen capability like the following.
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="xxxxx.UWP.App">
.......
<uap:LockScreen BadgeLogo="Assets\BadgeLogo.png" Notification="badgeAndTileText"/>
</uap:VisualElements>
</Application>
</Applications>
And set the app as main toast in the lock screen Setting page -> Personalization -> lock screen -> Choose one app to show detailed status on the lock screen If you have resisted the app, it will show in the apps list.
Code Sample
private void Button_Click(object sender, RoutedEventArgs e)
{
TileContent content = new TileContent()
{
Visual = new TileVisual()
{
LockDetailedStatus1 = "Hello world",
TileWide = new TileBinding() { }
}
};
var notification = new TileNotification(content.GetXml());
TileUpdateManager.CreateTileUpdaterForApplication().Update(notification);
}

With an iOS custom renderer, is there a way I can make a question mark item appear in a TextCell and open up a dialog box?

I have this XAML
<TableSection Title="Application">
<TextCell x:Name="appUpdated" Text="Updated" />
<TextCell x:Name="appVersion" Text="Application Version" />
</TableSection>
This C#:
public InfoPage()
{
InitializeComponent();
appUpdated.Text = AS.appUpdated;
appVersion.Text = AS.appVersion;
}
Is there a way that I can make a small question mark appear to the right of the Text and have clicking on that open up a dialog with an explanation?
Please note I am looking for an iOS solution with a custom renderer. I did before find some references about this but can't find examples any more.
Refer to this sample
Also need ViewCellRenderer and a little change.
replace the CellImageView in NativeiOSCell from UIImageView to UIButton, because we need click event to open a dialog box and show the info.
add button click event to show the additional info
CellImageView = new UIButton();
CellImageView.TouchUpInside += delegate
{
UIAlertView alert = new UIAlertView()
{
Title = HeadingLabel.Text,
Message = SubheadingLabel.Text
};
alert.AddButton("OK");
alert.Show();
};
modify the way how button get the image
CellImageView.SetBackgroundImage(GetImage(cell.ImageFilename),UIControlState.Normal);
adjust the frame of text and image.
public override void LayoutSubviews()
{
base.LayoutSubviews();
HeadingLabel.Frame = new CGRect(5, 4, ContentView.Bounds.Width - 63, 25);
CellImageView.Frame = new CGRect(ContentView.Bounds.Width - 63, 5, 33, 33);
}
This is my test.
PS: If you still have any confusions about my answer, I will try to upload a demo in github.

Disable Back button in Title bar for Droid and WP in XAML

Today I wanted to disable title bar button for Android and WindowsPhone as they have their own hardware back buttons and don't need another one in the title. As I started with pages coded in C# instead of XAML i knew about the OnPlatform directives and after I read this I thought of something like this:
<OnPlattform>
<OnPlatform.Android>
<NavigationPage HasBackButton="false" />
</OnPlatform.Android>
<OnPlatform.WinPhone>
<NavigationPage HasBackButton="false" />
</OnPlatform.WinPhone>
</OnPlattform>
This of course did not work. So i added the NavigationPage.HasBackButton="false" attribute to the ContentPage, which worked, but as far as i know this would disable the back button on all devices. In C# code I would do something like this:
NavigationPage.SetHasBackButton(this, Device.OnPlatform(true, false, false));
//Or this:
Device.OnPlatform(
() => { NavigationPage.SetHasBackButton(this, true); },
() => { NavigationPage.SetHasBackButton(this, false); },
() => { NavigationPage.SetHasBackButton(this, false); }
);
So what do I have to do to get this to work in XAML?

Toast equivalent for Xamarin Forms

Is there any way using Xamarin Forms (not Android or iOS specific) to have a pop-up, like Android does with Toast, that needs no user interaction and goes away after a (short) period of time?
From searching around all I'm seeing are alerts that need user clicks to go away.
There is a simple solution for this. By using the DependencyService you can easily get the Toast-Like approach in both Android and iOS.
Create an interface in your common package.
public interface IMessage
{
void LongAlert(string message);
void ShortAlert(string message);
}
Android section
[assembly: Xamarin.Forms.Dependency(typeof(MessageAndroid))]
namespace Your.Namespace
{
public class MessageAndroid : IMessage
{
public void LongAlert(string message)
{
Toast.MakeText(Application.Context, message, ToastLength.Long).Show();
}
public void ShortAlert(string message)
{
Toast.MakeText(Application.Context, message, ToastLength.Short).Show();
}
}
}
iOS section
In iOs there is no native solution like Toast, so we need to implement our own approach.
[assembly: Xamarin.Forms.Dependency(typeof(MessageIOS))]
namespace Your.Namespace
{
public class MessageIOS : IMessage
{
const double LONG_DELAY = 3.5;
const double SHORT_DELAY = 2.0;
NSTimer alertDelay;
UIAlertController alert;
public void LongAlert(string message)
{
ShowAlert(message, LONG_DELAY);
}
public void ShortAlert(string message)
{
ShowAlert(message, SHORT_DELAY);
}
void ShowAlert(string message, double seconds)
{
alertDelay = NSTimer.CreateScheduledTimer(seconds, (obj) =>
{
dismissMessage();
});
alert = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert);
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null);
}
void dismissMessage()
{
if (alert != null)
{
alert.DismissViewController(true, null);
}
if (alertDelay != null)
{
alertDelay.Dispose();
}
}
}
}
Please note that in each platform, we have to register our classes with DependencyService.
Now you can access out Toast service in anywhere in our project.
DependencyService.Get<IMessage>().ShortAlert(string message);
DependencyService.Get<IMessage>().LongAlert(string message);
You can use Acr.UserDialogs Package from nuget and code like below,
Acr.UserDialogs.UserDialogs.Instance.Toast(Message, new TimeSpan(3));
Here's a version of Alex Chengalan's iOS code that avoids the UI sticking when multiple messages are shown...
public class MessageIOS : IMessage
{
const double LONG_DELAY = 3.5;
const double SHORT_DELAY = 0.75;
public void LongAlert(string message)
{
ShowAlert(message, LONG_DELAY);
}
public void ShortAlert(string message)
{
ShowAlert(message, SHORT_DELAY);
}
void ShowAlert(string message, double seconds)
{
var alert = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert);
var alertDelay = NSTimer.CreateScheduledTimer(seconds, obj =>
{
DismissMessage(alert, obj);
});
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null);
}
void DismissMessage(UIAlertController alert, NSTimer alertDelay)
{
if (alert != null)
{
alert.DismissViewController(true, null);
}
if (alertDelay != null)
{
alertDelay.Dispose();
}
}
}
You can use SnackBar from Xamarin Community toolkit package, which uses native implementation in platforms where natively supported, because Toast is deprecated in API level 30, a SnackBar without an Action is equivalent to a Toast.
This method was deprecated in API level 30.
Custom toast views are deprecated. Apps can create a standard text toast with the makeText(android.content.Context, java.lang.CharSequence, int) method, or use a Snackbar when in the foreground. Starting from Android Build.VERSION_CODES#R, apps targeting API level Build.VERSION_CODES#R or higher that are in the background will not have custom toast views displayed. (source).
Starting with Xamarin Community toolkit
Install the Package on all your projects
include the namespace using Xamarin.CommunityToolkit.Extensions;
In your page code-behind show a SnackBar upon an event
await this.DisplayToastAsync("This is a Toast Message");
await this.DisplayToastAsync("This is a Toast Message for 5 seconds", 5000);
You may specify a duration for the SnackBar to disappear (in milliseconds) or leave the default one which equals 3 seconds.
Resources
SnackBar Sample
Official Repo https://github.com/xamarin/XamarinCommunityToolkit
Official Docs https://learn.microsoft.com/en-us/xamarin/community-toolkit/
EDIT
Anchored Toast: You may anchor the toast above a view (like screenshot above) by simply calling the extension method DisplayToastAsync() from that view (anchor) object instead from the page instance (this):
<Button x:name="floatingButton" .../>
await floatingButton.DisplayToastAsync("This is a Toast Message for 5 seconds", 5000);
Padding and corner radius: (starting from xct version 1.3.0 preview-1)
You can set the corner radius and the padding for your Toast like the following example:
var messageOptions = new MessageOptions
{
Message = "Toast with Padding and round corner",
Foreground = Color.White,
Font = Font.SystemFontOfSize(16),
Padding = new Thickness(20)
};
var options = new ToastOptions
{
MessageOptions = messageOptions,
CornerRadius = new Thickness(40, 40, 0, 0),
BackgroundColor = Color.FromHex("#CC0000")
};
await this.DisplayToastAsync(options);
PS: The same properties could be applied for the SnackBar view.
EDIT2
If what xct SnackBar offers doesn't fulfil your requirements or you want to display not only text but some complexe view, you might have to use a popup instead.
Adding to Alex's answer, here's the UWP variant:
public class Message : IMessage {
private const double LONG_DELAY = 3.5;
private const double SHORT_DELAY = 2.0;
public void LongAlert(string message) =>
ShowMessage(message, LONG_DELAY);
public void ShortAlert(string message) =>
ShowMessage(message, SHORT_DELAY);
private void ShowMessage(string message, double duration) {
var label = new TextBlock {
Text = message,
Foreground = new SolidColorBrush(Windows.UI.Colors.White),
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
};
var style = new Style { TargetType = typeof(FlyoutPresenter) };
style.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(Windows.UI.Colors.Black)));
style.Setters.Add(new Setter(FrameworkElement.MaxHeightProperty, 1));
var flyout = new Flyout {
Content = label,
Placement = FlyoutPlacementMode.Full,
FlyoutPresenterStyle = style,
};
flyout.ShowAt(Window.Current.Content as FrameworkElement);
var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(duration) };
timer.Tick += (sender, e) => {
timer.Stop();
flyout.Hide();
};
timer.Start();
}
}
Coloring and styling is up to you, the MaxHeightis actually required to keep the height at the minimum.
We'd normally use Egors Toasts plugin, but as it requires permissions on iOS for a current project we've gone a different route using Rg.Plugins.Popup nuget (https://github.com/rotorgames/Rg.Plugins.Popup).
I wrote a basic xaml/cs page of type PopupPage,
<?xml version="1.0" encoding="utf-8" ?>
<popup:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:popup="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
x:Class="YourApp.Controls.ToastPage">
...
and had it created by a service, whose interface you registered at app start or use Xamarin.Forms.DependencyService to fetch the service would be viable too.
The service news up the PopupPage derived page, and does
await PopupNavigation.PushAsync(newToastPage);
await Task.Delay(2000);
await PopupNavigation.PopAllAsync();
The Popup page can be dismissed by the user by tapping outside the page display (assuming it hasn't filled the screen).
This seems to work fine on iOS/Droid, but I'm open to correction if anyone knows what this is a risky way of doing it.
You can use IUserDialog NuGet and simply use it's toastAlert
var toastConfig = new ToastConfig("Toasting...");
toastConfig.SetDuration(3000);
toastConfig.SetBackgroundColor(System.Drawing.Color.FromArgb(12, 131, 193));
UserDialogs.Instance.Toast(toastConfig);
Here is a code snippet that I am using to show the toast in Xamarin.iOS
public void ShowToast(String message, UIView view)
{
UIView residualView = view.ViewWithTag(1989);
if (residualView != null)
residualView.RemoveFromSuperview();
var viewBack = new UIView(new CoreGraphics.CGRect(83, 0, 300, 100));
viewBack.BackgroundColor = UIColor.Black;
viewBack.Tag = 1989;
UILabel lblMsg = new UILabel(new CoreGraphics.CGRect(0, 20, 300, 60));
lblMsg.Lines = 2;
lblMsg.Text = message;
lblMsg.TextColor = UIColor.White;
lblMsg.TextAlignment = UITextAlignment.Center;
viewBack.Center = view.Center;
viewBack.AddSubview(lblMsg);
view.AddSubview(viewBack);
roundtheCorner(viewBack);
UIView.BeginAnimations("Toast");
UIView.SetAnimationDuration(3.0f);
viewBack.Alpha = 0.0f;
UIView.CommitAnimations();
}
I would recommend Plugin.Toast library from nuget. It works well.
CrossToastPopUp.Current.ShowToastMessage("my toast message");
or from ACR.UserDialogs Nuget libriary
UserDialogs.Instance.ShowLoading("Loading");
#MengTim, to fix the multiple toast issue in #alex-chengalan's solution, I simply wrapped everything within ShowAlert() with a check to see if alert and alertDelay are null, then within DismissMessage, nulled out alert and alertDelay.
void ShowAlert(string message, double seconds)
{
if(alert == null && alertDelay == null) {
alertDelay = NSTimer.CreateScheduledTimer(seconds, (obj) =>
{
DismissMessage();
});
alert = UIAlertController.Create(null, message, UIAlertControllerStyle.Alert);
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alert, true, null);
}
}
void DismissMessage()
{
if (alert != null)
{
alert.DismissViewController(true, null);
alert = null;
}
if (alertDelay != null)
{
alertDelay.Dispose();
alertDelay = null;
}
}
That seemed to at least clear up the UI hang, if you are looking for a quick fix. I was trying to display the toast on navigation to a new page, and believe that the PresentViewController being set was essentially cancelling out my navigation. Sorry I did not comment within the thread, my reputation is too low :(
This is my improved ShowAlert version of Ian Warburton's version to ensure that the toast is displayed even on popup page.
Furthermore, the toast is dissmissed if the user click outside the toast.
I used UIAlertControllerStyle.ActionSheet that look likes toast but it also work with UIAlertControllerStyle.Alert
void ShowAlert(string message, double seconds)
{
var alert = UIAlertController.Create(null, message, UIAlertControllerStyle.ActionSheet);
var alertDelay = NSTimer.CreateScheduledTimer(seconds, obj =>
{
DismissMessage(alert, obj);
});
var viewController = UIApplication.SharedApplication.KeyWindow.RootViewController;
while (viewController.PresentedViewController != null)
{
viewController = viewController.PresentedViewController;
}
viewController.PresentViewController(alert, true, () =>
{
UITapGestureRecognizer tapGesture = new UITapGestureRecognizer(_ => DismissMessage(alert, null));
alert.View.Superview?.Subviews[0].AddGestureRecognizer(tapGesture);
});
}
I hope this will help someone !
There is no built-in mechanism in Forms, but this nuget package supplies something similar
https://github.com/EgorBo/Toasts.Forms.Plugin
Note: These are not Android style toasts as requested in the question but UWP style toasts which are system wide notifications.
I customised a custom popup with Rg.Plugins.Popup NuGet
this is an example:
<pages:PopupPage.Animation>
<animations:ScaleAnimation
PositionIn="Center"
PositionOut="Center"
ScaleIn="1.2"
ScaleOut="0.8"
DurationIn="600"
DurationOut="600"
EasingIn="Linear"
EasingOut="Linear"/>
</pages:PopupPage.Animation>
<Frame CornerRadius="10"
HeightRequest="30"
VerticalOptions="End"
HorizontalOptions="Fill"
HasShadow="False"
Padding="0" Margin="40,50"
OutlineColor="LightGray">
<StackLayout
Opacity="0.4"
BackgroundColor="White">
<Label
x:Name="lbl"
LineBreakMode="WordWrap"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center" TextColor="Black" FontSize="12">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="iOS" Value="NewJuneMedium" />
</OnPlatform>
</Label.FontFamily>
</Label>
</StackLayout>
</Frame>
then in your basecontentpage you can add the following code, to show and hide the "toast" after a while:
public async void showpopup(string msg)
{
await Navigation.PushPopupAsync(new Toast(msg));
await Task.Delay(3000);
await Navigation.PopPopupAsync(true);
}
I used
https://github.com/ishrakland/Toast/
In
https://www.nuget.org/packages/Plugin.Toast/
Example:
CrossToastPopUp.Current.ShowToastMessage ("Loading", Plugin.Toast.Abstractions.ToastLength.Short);
Give it a try.
The iOS answers above worked for me but for one little problem -- a warning: Attempt to present UIAlertController ... whose view is not in the window hierarchy!
After some search, I came across this unrelated answer which helped. The poster commented "This looks stupid but works", which is right on both counts.
So, I modified the ShowAlert() function above with these lines, which seem to work:
var rootVC = UIApplication.SharedApplication.KeyWindow.RootViewController;
while ( rootVC.PresentedViewController != null) {
rootVC = rootVC.PresentedViewController;
}
rootVC.PresentViewController( alert, true, null);
For UWP
public void ShowMessageFast(string message)
{
ToastNotifier ToastNotifier = ToastNotificationManager.CreateToastNotifier();
Windows.Data.Xml.Dom.XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
Windows.Data.Xml.Dom.XmlNodeList toastNodeList = toastXml.GetElementsByTagName("text");
toastNodeList.Item(0).AppendChild(toastXml.CreateTextNode("Test"));
toastNodeList.Item(1).AppendChild(toastXml.CreateTextNode(message));
Windows.Data.Xml.Dom.IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
Windows.Data.Xml.Dom.XmlElement audio = toastXml.CreateElement("audio");
audio.SetAttribute("src", "ms-winsoundevent:Notification.SMS");
ToastNotification toast = new ToastNotification(toastXml);
toast.ExpirationTime = DateTime.Now.AddSeconds(4);
ToastNotifier.Show(toast);
}
Currently use xamarin essential in android:
//access mainthread
MainThread.BeginInvokeOnMainThread(() =>
{
Toast.MakeText(Application.Context, message, ToastLength.Short).Show();
});
Adding Alex's code, for UWP variant, I found a great implementation here
https://www.c-sharpcorner.com/article/xamarin/
Just come and leave a clap for him :)
[assembly:Xamarin.Forms.Dependency(typeof(Toast_UWP))]
namespace ToastMessage.UWP
{
class Toast_UWP : Toast
{
public void Show(string message)
{
ToastTemplateType toastTemplate = ToastTemplateType.ToastImageAndText01;
XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);
XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text");
toastTextElements[0].AppendChild(toastXml.CreateTextNode(message));
XmlNodeList toastImageAttributes = toastXml.GetElementsByTagName("image");
((XmlElement)toastImageAttributes[0]).SetAttribute("src", "ms-appx:///Assets/Logo.scale-240.png");
((XmlElement)toastImageAttributes[0]).SetAttribute("alt", "logo");
IXmlNode toastNode = toastXml.SelectSingleNode("/toast");
((XmlElement)toastNode).SetAttribute("duration", "short");
var toastNavigationUriString = "#/MainPage.xaml?param1=12345";
var toastElement = ((XmlElement)toastXml.SelectSingleNode("/toast"));
toastElement.SetAttribute("launch", toastNavigationUriString);
ToastNotification toast = new ToastNotification(toastXml);
ToastNotificationManager.CreateToastNotifier().Show(toast);
}
}
}
By default, your messages will be queued and notified one after one, delayed based on the message duration. If you want to replace the existing message by the new one immediately just add more code like below
ToastNotificationManager.History.Remove("YOUR_TAG");
// Code to create Toast message, like the above method
toast.Tag = "YOUR_TAG";
If you want to add audio to your toast message, add this to your code
var audio = toastXml.CreateElement("audio");
audio.SetAttribute("src", "ms-winsoundevent:Notification.Default");
Install nuget Acr.UserDialogs.
It contains Toasts exactly what you are looking for.
ToastEvent toastEvent = new ToastEvent();
var toastConfig = new ToastConfig(toastEvent,"Toasting...","");
toastConfig.SetDuration(2000);
UserDialogs.Instance.Toast(toastConfig);
You could use the Xamarin.Toolkit and follow this information provided by MS.
https://learn.microsoft.com/en-us/xamarin/community-toolkit/views/popup
In my application I could manage it by putting every code-thing between a viewmodel, the view and a method called DismissThisPopup(). So it is possible to controll it from outside of the current Mainpage.
To acomplish your request.
You could call await Task.Delay(5000); //as example 5sec
after you called your popup.Open();
so it might look like:
...
var vm = new MyPopUpViewModel()
vm.DisplayText = "this could be your text";
vm.DelayTimeForDismiss = 5000;
vm.IsLightDismissAllowed = false; //used that you can not close the popup by clicking around
await vm.OpenPopupAsync();
then in your vm OpenPopUpAsync()
...other properties and stuff
internal PopUpLoadingView popup = new PopUpLoadingView();//this is the view created with the informations from MS
public async Task OpenPopUp()
{
popup.BindingContext = this;
Application.Current.MainPage.Navigation.ShowPopup(popup: popup);
await Task.Delay(DelayTimeForDismiss);
popup.DismissThisPopup();
}
and in your PopUpLoadingView, insert this method:
...other stuff
public void DismissThisPopup()
{
Dismiss(this);
}
You can use DisplayAlert("", "", "", "" );

How To Create A Bottom Or Top AppBar in Windows Store App Using C#?

I'm aware of the way to create the AppBar via XAML code. I want to know how to create the AppBar via C#.
On the Windows Phone App, i can just do this.
ApplicationBar = new ApplicationBar(){
Mode = ApplicationBarMode.Minimized
};
ApplicationBarMenuItem copyLinkButton = new ApplicationBarMenuItem();
copyLinkButton.Click += (sender, e) => { //action };
copyLinkButton.Text = "copy to clipboard";
ApplicationBar.MenuItems.Add(copyLinkButton);
ApplicationBarMenuItem openInIEButton = new ApplicationBarMenuItem();
openInIEButton.Click += (sender, e) => { //action };
openInIEButton.Text = "open in internet explorer";
ApplicationBar.MenuItems.Add(openInIEButton);
How do i do it in Windows Store App?
Update
Thank you #kimsk for giving me an answer to my previous question. I've solved it with your answer. But after solving that problem, another similar problem surfaced.
Because i didn't simply use a button like this,
<Button>Button 3</Button>
I have problem tapping into the Microsoft's default style. Is there anyway to reference to that particular style or do i have to create one from scratch by myself?
<Button Style="{StaticResource EditAppBarButtonStyle}"/>
Thanks again!
It's pretty straightforward if you think about XAML is just a declarative way to create objects of UIElement elements such as AppBar, Button, StackPanel, and so on.
Here is the code to create a BottomAppBar in XAML that you already know:
<Page.BottomAppBar>
<AppBar>
<StackPanel Orientation="Horizontal">
<Button>Button 3</Button>
<Button>Button 4</Button>
</StackPanel>
</AppBar>
</Page.BottomAppBar>
Here is the C# code that creates a TopAppBar:
var appBar = new AppBar();
var stackPanel = new StackPanel{Orientation = Orientation.Horizontal};
stackPanel.Children.Add(new Button { Content = "Button1" });
stackPanel.Children.Add(new Button { Content = "Button2" });
var buttonWithStyle = new Button();
buttonWithStyle.Style = Application.Current.Resources["EditAppBarButtonStyle"] as Style;
stackPanel.Children.Add(buttonWithStyle);
appBar.Content = stackPanel;
this.TopAppBar = appBar;
Notice the pattern? :-)
And this is the screenshot:
Hope this helps!

Categories