New Feature in Xamarin.Form with Fontawesome 5 not working - xamarin.forms

I would like to use the new feature in Xamarin.Forms enabling Fonts cross-platform but I can't get it to work properly.
Version Xamarin.Forms: 4.7.0.1080
Here's part of my code.
<Button Text=""
FontFamily="FA5Regular"
Command="{Binding Path=BindingContext.Delete, Source={x:Reference SongsCollectionView}}"
CommandParameter="{Binding .}"
Grid.Column="3" Grid.Row="0" StyleClass="Delete"/>
In app.xaml.cs:
[assembly: ExportFont("Font Awesome 5 Free-Regular-400.otf", Alias = "FA5Regular")]
[assembly: ExportFont("Font Awesome 5 Free-Solid-900.otf", Alias ="FA5Solid")]
namespace eTabber
{
public partial class App : TxfApplication
{
...
Styling:
Button {
background-color: darkslateblue;
color: white;
border-radius: 5;
}
Button.Delete {
background-color: red;
}
In the solution:
It should produce a button with a trashcan (far fa-trash-alt) but it produces a rectangle.
== EDIT ==
It maybe very well possible the alias from the ExportFontAttribute (FA5Regular) should be different. I don't see it anywhere at runtime:
== EDIT ==
Decompiled with JustDecompile and I do see the fonts in the eTabber.dll:
== Edit ==
There's part of an answer here but can't get that to work either.

You have font awesome licence issue, Try with "solid" icons, many of them regular doesn't support.
https://fontawesome.com/download
You can find all icon code in a code files and information
https://github.com/matthewrdev/fa2cs
For example; Four support only Solid for free lib.
/// <summary>
/// fa-4 unicode value ("\u0034").
/// <para/>
/// This icon supports the following styles: Light (Pro), Regular (Pro), Solid, Duotone (Pro), Thin (Pro)
/// <para/>
/// Introduced in '6.0.0-beta1', Last Modified in '6.0.0-beta1'.
/// <para/>
/// See https://fontawesome.com/icons/4
/// </summary>
public const string Four = "\u0034";

Related

Icomoon, open-iconic SVG icons not displaying in the blazor page

I'm trying to use Icomoon in my blazor project. I've already downloaded the icons.
HTML
<button class="search__button">
<svg class="search__button__icon">
<use xlink:href="img/icons/symbol-defs.svg#magnifying-glass.svg"></use>
</svg>
</button>
CSS
.search__button {
&__icon {
color: #444444;
width: 1.75rem;
height: 1.75rem;
}
}
The location of the SVG files
The result I'm getting
Am I missing something? I think to have followed what it's said in the documentation.
Thanks for helping
EDIT
In this documentation is says that the svg icon can be used as an image like this:
<img class="nav__level-item__icon" src="img/icons/svg/home.svg" alt="home">
When used like this, it's displaying.
&__icon {
width: 1.75rem;
height: 1.75rem;
fill: #fff; //and/or color: #fff
}
The only problem with using it as an image is that I can't style it. So, at the end, I'm still stuck.
EDIT 2
I tried to implement what's suggested in this blog post. Icons are being displayed, I can't still style them.
According to Microsoft SVG use is a still limited, in this Microsoft document it states
If you place an <svg> tag directly into a component file (.razor), basic image
rendering is supported but many advanced scenarios aren't yet supported. For
example, <use> tags aren't currently respected
If you use a string variable for the xlink:href attribute the icon will render after pre-rendering but would disappear as soon as the Blazor library was loaded in the client, but looks like there is a workaround.
Instead of putting the svg and use tags in the .razor file you can return a MarkupString instead, something like
<i class="icon">
#IconMarkupString
</i>
#code {
[Parameter]
public string IconSprite { get; set; }
private MarkupString IconMarkupString
{
get => new MarkupString($"<svg class='icon-sprite'><use xlink:href='{IconSprite}'/></svg>");
}
}
Then used like
<SVGIcon IconSprite="img/icons/symbol-defs.svg#magnifying-glass" />
One thing that I did notice was in order to get the styling to work on the SVG element itself I had to add a separate class to the SVG tag otherwise the styling would not be applied even when using ::deep.

Ionic set Focus programmatically

I am using ionic with angular in a component and I am trying to set focus programmatically after the page loads up.
This is the code
item.component.html:
<ion-row>
<ion-col col-5>
<ion-item >
<ion-label>Departure Port</ion-label>
<ion-select #selected class="selector" formControlName="control"
[(ngModel)]="modelItem"
(click)="selectItem()">
<ion-option
*ngFor="let item of [{code:item.code, desc:item.desc}]"
value="{{item.code}}">
{{item.desc}} ({{item.code}})
</ion-option>
</span>
</ion-select>
</ion-item>
</ion-col>
</ion-row>
item.component.ts
export class Item Component implements OnInit, AfterViewInit, AfterViewChecked {
#ViewChild('selector')
private selectorElRef: Select;
public ngAfterViewInit(): void {
this.portSelectorElRef.setFocus();
}
I have also tried this:
#ViewChild('selector')
private selectorElRef: Select;
public ngAfterViewInit(): void {
this.portSelectorElRef.getElementRef().nativeElement.focus();
}
And this:
#ViewChild('selector')
private selectorElRef: Select;
public ngAfterViewInit(): void {
this.portSelectorElRef.getNativeElement.focus();
}
variables.scss
*:focus {
border: solid $primary-color 2px;
box-shadow: 5px 10px 8px $primary-color;
}
None of the above is setting the focus on the given item. I have tried to set the focus in AfterViewInit and in AfterViewChecked - the same effect (none).
Tabbing to set the focus works fine and the styling is being applied, but I can't seem to be able to get the focus programmatically.
So maybe not exactly what you would want to hear but I will try to help with the following:
Browser support for such behavior is fragmented: Safari and Chrome have different "policy" of how this should work, and to say it simple - modern Safari wants only end user explicit interaction to call focus on elements, while Chrome should allow you to do what you are trying to do.
The .focus method itself is only applicable to specific standard web elements: input, button etc
The HTMLElement.focus() method sets focus on the specified element, if it can be focused.
Source: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
in your case you are trying to apply it to Ionic component ion-select which unfortunately does not have focusable elements.
See this stackblitz and look at the console and you will see that ion-select does not really have a native button element (it is another component that uses "span" & div etc).
So essentially you are trying to apply focus to elements that do not take on focus programmatically.
If you can explain what UX you are trying to achieve - maybe that can be achieved in a different manner?
For example you could call .open() method that ion-select supports to open up the selector on load:
https://stackblitz.com/edit/ionic-r8issn
You would basically leverage normal API from here: https://ionicframework.com/docs/api/components/select/Select/#open

FontAwesome in Xamarin forms UWP

I have a Custom renderer working in Android with Fontawesome.
I was following this guide using font awesome in UWP
With a custom Label type to try to get Fontawesome working in UWP.
public class FontAwesomeLabel: Xamarin.Forms.Label {
public FontAwesomeLabel() {
switch (Device.RuntimePlatform)
{
case Device.UWP:
FontFamily = #"/Assets/FontAwesome.otf#FontAwesome";
break;
}
}
}
The fonts
were loaded as both ttf and otf. I have tried both types.
They Assest fonts have build action "Content"
mainView.Children.Add( new FontAwesomeLabel()
{Text = FaConstPool.FASearch ,FontSize = 40});
public static string FASearch = "\uf002";
Only works on Android and not in UWP
I see a strange box and not the expected Fontawesome icon as for Android.
Any ideas what i have done wrong ?
The solution to the problem turned out to be in UWP, use the correct font family name.
Font Awesome 5 Free Solid
and not just "FontAwesome"
// FontFamily = #"/Assets/FontAwesome.otf#FontAwesome"; // incorrect font family name
FontFamily = #"/Assets/Fonts/FontAwesome.otf#Font Awesome 5 Free Solid";
For anyone interested in details:
I downloaded a font editor to check the internal font name and font family name. I made the mistake of code copying blog posts that used values from similar/older fonts. See image for actual content.
There are 2 types of solution I got to work:
1) A custom control in shared code /.netStandard Common project.
2) a custom renderer
Solution 1: Custom Label
public class FontAwesomeLabel: Xamarin.Forms.Label
{
public FontAwesomeLabel()
{
switch (Device.RuntimePlatform)
{
case Device.UWP:
// make sure the correct font family name is used. Check in a font editor
this.FontFamily = #"/Assets/Fonts/FontAwesome.otf#Font Awesome 5 Free Solid";
break;
}
}
}
Solution 2: Customer renderer on Standard Control
[assembly: ExportRenderer(typeof(Label), typeof(FontAwesomeLabelRenderer))]
namespace Oxando.UWP.CustomRenderers
{
public class FontAwesomeLabelRenderer : LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (Control != null)
{
// on UWP be sure use the Font Family name.
// get a font editor and check the name, if it doesnt match UWP wont load it
if (FontAwesomeUtil.CheckIsFA(e.NewElement.Text))
{
Control.FontFamily = new FontFamily("/Assets/Fonts/FontAwesome.otf#Font Awesome 5 Free Solid");
}
}
}
}
internal static class FontAwesomeUtil
{
public static bool CheckIsFA(string text)
{
if (text.Length == 0) return false;
if (text.Length > 1 || text[0] < 0xf000) return false;
return true;
}
}
}
Actual internal names as shown in Font editor
The correct path to add a font on UWP is /Assets/Fonts/FontAwesome.ttf#FontAwesome it seems you have to add the Fonts folder.
Like this:
Additionally you can use Iconize plugin and check this answer:
How can I display a font awesome glyph in XAML/C#

GWT ListBox rendering different across browsers

So, I have a custom implementation of ListBox for a GWT application
Its xml code looks like this:
<g:FlowPanel addStyleNames="{style.yearRangePanel}">
<g:FlowPanel addStyleNames="{style.rangeSeparator} {style.paddingTop}">
<g:Label addStyleNames="{style.horizontalAlign}" ui:field="integerRangeDropdownLabel">Filter studies by range of enroled patients: </g:Label>
<g:Label addStyleNames="{style.prefixSpace} {style.horizontalAlign}" ui:field="startSampleSizeLabel"/>
</g:FlowPanel>
<g:FlowPanel ui:field="integerRangeDropdownFilterPanel" addStyleNames="{style.yearRangeSliderPanel} {style.paddingTop}">
<g:ListBox ui:field ="integerRangeDropdownListBox" styleName="{style.customListBox}"/>
</g:FlowPanel>
</g:FlowPanel>
And its main java code looks like:
#UiConstructor
public IntegerRangeDropdownFilterComposite (String fieldName, String labelText){
this.initWidget(uiBinder.createAndBindUi(this));
filterChangedEvent = new FilterChangedEvent(fieldName);
FilterConfig filterConfig = clientFactory.getApplicationContext().getConfig(FilterConfig.class);
List<FilterSetting> filterSettings = filterConfig.getFilterConfigBy(fieldName);
FilterSetting filterSetting = filterSettings.get(0);
filterByIntegerRangeSettings = (FilterConfig.FilterByIntegerRangeSettings) filterSetting;
this.increment = Integer.toString(filterByIntegerRangeSettings.getIncrement());
this.minSampleSize = Integer.toString(filterByIntegerRangeSettings.getInitialValue());
this.maxSampleSize = Integer.toString(filterByIntegerRangeSettings.getEnd());
this.setupConfig(fieldName);
}
private void setupConfig(String fieldName){
setupRange(fieldName);
}
#Override
protected void onLoad() {
super.onLoad();
integerRangeDropdownFilterPanel.add((Widget) integerRangeDropdownListBox);
}
public void resetIntegerRangeDropdownFilter() {
filterChangedEvent.resetField();
}
#UiHandler("integerRangeDropdownListBox")
public void clickEnroled(ChangeEvent changeEvent){
if(integerRangeDropdownListBox.getSelectedIndex()!=0) {
String selectedItem = integerRangeDropdownListBox.getSelectedItemText();
minSampleSize = selectedItem.substring(0, (selectedItem.indexOf('-'))).trim();
maxSampleSize = selectedItem.substring((selectedItem.indexOf('-') + 1)).trim();
}
else{
minSampleSize="0";
maxSampleSize="100000";
}
resetIntegerRangeDropdownFilter();
filterChangedEvent.addFilter(Integer.parseInt(minSampleSize), Integer.parseInt(maxSampleSize));
clientFactory.getEventBus().fireEvent(filterChangedEvent);
}
Now, as for the style, I've tried "bootstrapping" it with this line:
<g:ListBox ui:field ="integerRangeDropdownListBox" styleName="btn btn-primary dropdown-toggle"/>
And I've tried customizing it with CSS like this:
.customListBox{
background-color: dodgerblue !important;
color: white;
padding: 5px;
}
<g:ListBox ui:field ="integerRangeDropdownListBox" styleName="{style.customListBox}"/>
Whichever way I do it, it will not render equally across browsers, it only looks "nice" on Google Chrome, while in Safari and Firefox it will have an "uglee" arrow for the dropdown and different scroll bar.
Any ideas as for why this may be happening? Needless to say I've tried google and the forum, but searching for GWT related topics is pretty much useless
First, you should use addStyleNames instead of styleName, because styleName removes all existing style names and replaces them with the style name you provided.
Second, this is not a GWT problem. Browsers render various elements differently. If you want a more uniform look, you need to search for CSS suggestions.
It is exactly as you described your question: The standard GWT ListBox is rendering different across browsers.
The main reason is that it is using a native browser control under the hood.
It creates a HTML select control element here.
You can try that basic HTML control yourself in different browsers here.
So there is not much you can do about that.
On some browser you might be able to style it, but not consistently.

Google Web Toolkit - UiBinder with CSS styling

I am new in GWT. Here is my questions:
Form.css
.text{
color: orange;
font-size: 16pt;}
FormResources.java
public interface FormResources extends ClientBundle{
#Source("Form.css")
MyCSS style();
public interface MyCSS extends CssResource{
String text();
}}
Form.ui.xml
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:res="urn:with:com.org.yournamehere.client.FormResources">
<ui:with field='res' type='org.yournamehere.client.FormResources' />
<g:HTMLPanel>
<g:Label res:styleName="style.text">ABC</g:Label>
</g:HTMLPanel></ui:UiBinder>
Form.java
public class Form extends Composite {
private static final FormUiBinder uiBinder = GWT.create(FormUiBinder.class);
#UiTemplate("Form.ui.xml")
interface FormUiBinder extends UiBinder<Widget, Form> {}
#UiField(provided = true)
final FormResources res;
public Form() {
this.res = GWT.create(FormResources.class);
res.style().ensureInjected();
initWidget(uiBinder.createAndBindUi(this));
}}
My problem is can show the ABC word, but not in orange color and size is 16pt. The Css part cannot shown. Please help me to solve this problem. Thanks.
You are almost doing right.
Just replace below line in Form.ui.xml file.
<g:Label res:styleName="style.text">ABC</g:Label>
with
<g:Label res:styleName="{res.style.text}">ABC</g:Label>
screenshot:
Problem : "style.text" is not referring to your style defined in FormResources#MyCSS#text.
Always enclose the value in {...} if you want to use some dynamic values.
For more info have a look at sample on GWT UiBinder - Hello Stylish World

Resources