Issue with FontImageSource Glyph when using a Binding - c#

Using Xamarin Forms 5 and Visual Studio 2022.
I have added the materialdesignicons-webfont.ttf to a Fonts folder of the PCL project only and marked it as an Embedded Resource.
I have added the following in the AssemblyInfo.cs file:
[assembly: ExportFont("materialdesignicons-webfont.ttf", Alias = "mdi")]
The following XAML works fine:
<Image x:DataType="models:IPageResourceProvider"
BackgroundColor="Transparent"
IsVisible="{Binding IconType, Converter={StaticResource IconTypeConverter}, ConverterParameter={x:Static enums:IconType.MaterialDesignIcon}}">
<Image.Source>
<FontImageSource Glyph="󰭕"
FontFamily="mdi"
Size="32"
Color="Black" />
</Image.Source>
</Image>
But I want to bind the Glyph, however the following just shows a 5 as the Image (the last character of the unicode):
<Image x:DataType="models:IPageResourceProvider"
BackgroundColor="Transparent"
IsVisible="{Binding IconType, Converter={StaticResource IconTypeConverter}, ConverterParameter={x:Static enums:IconType.MaterialDesignIcon}}">
<Image.Source>
<FontImageSource Glyph="{Binding IconName}"
FontFamily="mdi"
Size="32"
Color="Black" />
</Image.Source>
</Image>
The interface IPageResourceProvider has the following property:
string IconName {get; }
And the implementation returns:
string IconName => "\uF0B55";
I can't work out what I'm doing wrong with this, any thoughts welcomed.

In C# represent a UTF-32 glyph using 4 bytes.
Example in C# for glyph U+10FFFD. Please note the upper case U:
public string IconName => "\U0010FFFD";
See also the note on four-digit and eight-digit Unicode escape codes here.
Example in XAML for glyph U+10FFFD:
Glyph="􏿽"

Related

How to use a font unicode that is stored in c#

I have a list of objects called SidebarItems, this list may change according to what Module the user is in. I have downloaded and got Font Awesome Pro working in my application, However I must use the Unacode to access the correct icon inside the font.
The SidebarNavItem
public record SidebarNavItem(string Title, string ViewName, string IconUnicode);
public class SidebarItems:IReadOnlyCollection<SidebarNavItem>
{
//Left this out for brevity
}
The Xaml That its being used
<Button Style="{StaticResource LabeledIconButton}"
Content="{Binding IconUnicode}" Grid.Row="0"
behaviors:ButtonBehavior.Label="{Binding Title}"
Command="{Binding NavigateCommand}"
CommandParameter="{Binding ViewName}"/>
This is what I'm getting but when I type it into the button, I get this:
<Button Style="{StaticResource LabeledIconButton}"
Content="" Grid.Row="0"
behaviors:ButtonBehavior.Label="{Binding Title}"
Command="{Binding NavigateCommand}"
CommandParameter="{Binding ViewName}"/>
How can I store these codes in SidebarItems?
Replace &#x with \u and remove the trailing ; from the string value returned from the property.
So  becomes:
public string IconUnicode => "\uf319";

Display multiline DynamicResource Label

I wish to add a Label in WPF that displays string from two different DynamicResources.
I want each DynamicResource to be on a new line.
My existing code is:
<Label x:Name="MyTextDisplay"
Grid.Row="3"
Grid.ColumnSpan="2"
Background="Red"
BorderBrush="Blue"
BorderThickness="1"
Margin="2, 2, 2, 2">
<TextBlock TextWrapping="Wrap" Text="{DynamicResource MyTextLine1}" Grid.ColumnSpan="2"/>
</Label>
I have another DynamicResource called MyTextLine2 that I want to display below MyTextLine1 but in the same Label.
How can I do this?
I have looked at these examples here but they dont display on new lines: How to bind multiple values to a single WPF TextBlock?
I faced the same problem and finally I found a solution.
Just use \r\n linebreak instead of just \n.
So, your resourse must look like:
<system:String x:Key="MyText" xml:space="preserve">Line 1
Line 2</system:String>
I realy don't know why this notation must be used only for dynamic resources, but it works for me

Binding an Image in WPF MVVM

I am having some trouble binding in Image to my viewmodel. I finally got rid of the XamlParseException, but the image does not come up. I even hard coded the image in the ViewModel. Can someone see what I am doing wrong?
View:
<Image HorizontalAlignment="Left" Margin="0,0,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Bottom" Grid.Row="8" Width="200" Grid.ColumnSpan="2" >
<Image.Source>
<BitmapImage DecodePixelWidth="200" UriSource="{Binding Path=DisplayedImage, Mode=TwoWay}" />
</Image.Source>
ViewModel:
string _DisplayedImagePath = #"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg";//string.Empty;
int _DisplayedImageIndex;
BitmapImage _DisplayedImage = null;
public BitmapImage DisplayedImage
{
get
{
_DisplayedImage = new BitmapImage();
if (!string.IsNullOrEmpty(_DisplayedImagePath))
{
_Rail1DisplayedImage.BeginInit();
_Rail1DisplayedImage.CacheOption = BitmapCacheOption.OnLoad;
_Rail1DisplayedImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
_Rail1DisplayedImage.UriSource = new Uri(_DisplayedImagePath);
_Rail1DisplayedImage.DecodePixelWidth = 200;
_Rail1DisplayedImage.EndInit();
}
return _Rail1DisplayedImage;
}
set
{
_Rail1DisplayedImage = value;
OnPropertyChanged("DisplayedImage");
}
}
Displaying an Image in WPF is much easier than that. Try this:
<Image Source="{Binding DisplayedImagePath}" HorizontalAlignment="Left"
Margin="0,0,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Bottom"
Grid.Row="8" Width="200" Grid.ColumnSpan="2" />
And the property can just be a string:
public string DisplayedImage
{
get { return #"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg"; }
}
Although you really should add your images to a folder named Images in the root of your project and set their Build Action to Resource in the Properties Window in Visual Studio... you could then access them using this format:
public string DisplayedImage
{
get { return "/AssemblyName;component/Images/ImageName.jpg"; }
}
UPDATE >>>
As a final tip... if you ever have a problem with a control not working as expected, simply type 'WPF', the name of that control and then the word 'class' into a search engine. In this case, you would have typed 'WPF Image Class'. The top result will always be MSDN and if you click on the link, you'll find out all about that control and most pages have code examples as well.
UPDATE 2 >>>
If you followed the examples from the link to MSDN and it's not working, then your problem is not the Image control. Using the string property that I suggested, try this:
<StackPanel>
<Image Source="{Binding DisplayedImagePath}" />
<TextBlock Text="{Binding DisplayedImagePath}" />
</StackPanel>
If you can't see the file path in the TextBlock, then you probably haven't set your DataContext to the instance of your view model. If you can see the text, then the problem is with your file path.
UPDATE 3 >>>
In .NET 4, the above Image.Source values would work. However, Microsoft made some horrible changes in .NET 4.5 that broke many different things and so in .NET 4.5, you'd need to use the full pack path like this:
<Image Source="pack://application:,,,/AssemblyName;component/Images/image_to_use.png">
For further information on pack URIs, please see the Pack URIs in WPF page on Microsoft Docs.
If you have a process that already generates and returns an Image type, you can alter the bind and not have to modify any additional image creation code.
Refer to the ".Source" of the image in the binding statement.
XAML
<Image Name="imgOpenClose" Source="{Binding ImageOpenClose.Source}"/>
View Model Field
private Image _imageOpenClose;
public Image ImageOpenClose
{
get
{
return _imageOpenClose;
}
set
{
_imageOpenClose = value;
OnPropertyChanged();
}
}
#Sheridan thx.. if I try your example with "DisplayedImagePath" on both sides, it works with absolute path as you show.
As for the relative paths, this is how I always connect relative paths, I first include the subdirectory (!) and the image file in my project.. then I use ~ character to denote the bin-path..
public string DisplayedImagePath
{
get { return #"~\..\images\osc.png"; }
}
This was tested, see below my Solution Explorer in VS2015..
)
Note: if you want a Click event, use the Button tag around the image,
<Button Click="image_Click" Width="128" Height="128" Grid.Row="2" VerticalAlignment="Top" HorizontalAlignment="Left">
<Image x:Name="image" Source="{Binding DisplayedImagePath}" Margin="0,0,0,0" />
</Button>

Adding a custom font to a windows phone 8 app

I've read articles such as this 31 days of windows phone day 24 embedding-fonts and this windows 8 xaml tips custom fonts that explain very clearly and simply how to do this.
But for some reason I can't figure out, my custom font doesn't show on my app, whether in the designer view or when I run it.
To be sure I haven't left any step out, I'm showing what I did here for any suggestions on what my issue might be:
1. First, this is my xaml textblock code
<StackPanel Grid.Row="1" x:Name="BottomPanel" Height="120" Width="800" Orientation="Horizontal">
<StackPanel.Background>
<SolidColorBrush Color="{StaticResource PhoneSemitransparentColor}"/>
</StackPanel.Background>
<TextBlock x:Name="MainTextBlock" FontFamily="/Fonts/KOMIKAX_.ttf" TextWrapping="Wrap" Text="Hello" Width="680" Height="120" Margin="10,0,0,0" FontSize="25" Padding="20,10"/>
</StackPanel>
2. I created a folder in my project, called it "Fonts" and that is where I copied my font file.
3. I changed the Build Action of the font file to Content. I left the Copy To Output Directory property as None at first, then changed it to Copy If Newer. No success.
What have I done wrong or what did I leave out?
This work for me.
First make a folder in your App with the name Fonts, then Add font to it, then use the following syntax. I used it, it works perfectly.
<TextBlock FontFamily="/Fonts/Comic.ttf#Comic" TextWrapping="Wrap" Text="Hello" FontSize="25"/>
Make sure that the Build Action must be set to Content,
Right Click on font in folder and click property, then select Build Action as Content, otherwise it will not work on Emulator and Device.
Try using this
<TextBlock x:Name="MainTextBlock" FontFamily=".\Fonts\KOMIKAX_.ttf#Komika Axis" TextWrapping="Wrap" Text="Hello" Width="680" Height="120" Margin="10,0,0,0" FontSize="25" Padding="20,10"/>
In case this doesn't work, remember the format is .\FontPath\FontFileName.ttf#FontName

Why do my images show at designtime and not at runtime?

I have a WPF <Image> that I am trying to display on a <Button> inside of a <Toolbar> with the following code.
<ToolBarTray>
<ToolBar Height="26" Name="toolBar1" VerticalAlignment="Top" >
<Button Name="StampButton" Click="StampButton_Click">
<Image Source="/MyApp.Resources;component/Resources/MyImage.png"
Height="16" Width="16" Stretch="Fill"/>
</Button>
</ToolBar>
</ToolBarTray>
The image shows up just fine at design time. However, at runtime nothing is displayed. The resources are in another dll called MyApp.Resources. The button is actually created just fine and the click event works fine also.
Set your image build action to "Resource". Try to use full source path.
I was getting same problem - image displaying at design time, but not at runtime.
I had build action set to resource, tried different pack uris etc etc, but solution was simple
<Window.Resources>
<BitmapImage x:Key="your_image_key" UriSource="your_image.png" />
<Image Source="{StaticResource your_image_key}"/>
</Window.Resources>
This is what worked for me, from a site called wpf-tutorial.com:
<Image Source="/WpfTutorialSamples;component/Images/copy.png" />
Images is a subfolder of the project folder in my case, and I assume also in this sample.

Categories

Resources