Reference ResourceDictionary in UWP Class Library - xaml

We have a UWP app using Template 10. Resources are in a UWP class library in the same solution. When we run the app we get the error
{Windows.UI.Xaml.Markup.XamlParseException:Cannot locate resource from ‘ms-resource:///Files/Styles\ButtonStyle.xaml’.
In App.xaml we have
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles\Custom.xaml" />
<ResourceDictionary Source="Styles\ButtonStyle.xaml"/>
<ResourceDictionary Source="Styles\ListsStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
We followed guidance in
Windows 10 Universal Merged Dictionaries
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ms-appx:///Styles/Custom.xaml" />
<ResourceDictionary Source="ms-appx:///Styles/ButtonStyle.xaml"/>
<ResourceDictionary Source="ms-appx:///Styles/ListsStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
then the error is
{Windows.UI.Xaml.Markup.XamlParseException: Failed to assign to property 'Windows.UI.Xaml.ResourceDictionary.Source' because the type 'Windows.Foundation.String' cannot be assigned to the type ...
We also tried the solution in ResourceDictionary in separate library
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/LibraryName;component/Styles/Custom.xaml" />
<ResourceDictionary Source="pack://application:,,,/LibraryName;component/Styles/ButtonStyle.xaml"/>
<ResourceDictionary Source="pack://application:,,,/LibraryName;component/Styles/ListsStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
then the error is
{Windows.UI.Xaml.Markup.XamlParseException: Cannot locate resource from pack://application:,,,/LibraryName;component/Styles/Custom.xaml’
How do we reference a ResourceDictionary in a UWP Class Library?

As #Justin has pointed out, the problem here is that you forgot to add the Class Library Name in your URI. Let's assume you have a UWP Class Library named "ClassLibrary1" in your solution. Then you can merge them like:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ClassLibrary1/Styles/Custom.xaml" />
<ResourceDictionary Source="ClassLibrary1/Styles/ButtonStyle.xaml"/>
<ResourceDictionary Source="ClassLibrary1/Styles/ListsStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Or
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ms-appx:///ClassLibrary1/Styles/Custom.xaml" />
<ResourceDictionary Source="ms-appx:///ClassLibrary1/Styles/ButtonStyle.xaml"/>
<ResourceDictionary Source="ms-appx:///ClassLibrary1/Styles/ListsStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Also don't forget to add "ClassLibrary1" into your main project's References.
Besides, if your class library is not in the same solution, then you will need to check the "Generate library layout" option in the Build configuration under the class library's Properties page.
Because in WinRT environment, the resources are no longer embedded in the assembly but are placed next to the dll as content. So we need to generate library layout so that we can reference the dll in other project conveniently. For more info, please see my previous answer.

Related

How to get the default shell flyout icon to react when android dark theme is switched on/off

I have an app which uses the shell flyout. When I added the flyout, it automatically created an icon as shown in the image below:
However, when I switch the android dark theme off:
The flyout icon remains white making it difficult to see:
I am using AppThemeBinding to automatically theme the app accordingly based on the system theme selected by the user, but I do not know how to change the flyout icon to a darker color if the user switches off the dark theme from the android settings.
Any idea how to do that?
The AppShell.xaml currently looks like this:
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="MAUIApp1.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MAUIApp1"
FlyoutBackgroundColor="{AppThemeBinding Light=#f2f2f2, Dark=#2a2a2a}">
<Shell.Resources>
<ResourceDictionary>
...
</ResourceDictionary>
</Shell.Resources>
<Shell.FlyoutHeader>
...
</Shell.FlyoutHeader>
<Shell.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</Shell.ItemTemplate>
<FlyoutItem Title="Item1" Icon="item1.svg">
<ShellContent ContentTemplate="{DataTemplate local:page1}" Route="page1"/>
</FlyoutItem>
<FlyoutItem Title="Item2" Icon="item2.svg">
<ShellContent ContentTemplate="{DataTemplate local:page2}" Route="page2"/>
</FlyoutItem>
<FlyoutItem Title="Item3" Icon="item3.svg">
<ShellContent ContentTemplate="{DataTemplate local:page3}" Route="page3"/>
</FlyoutItem>
<Shell.FlyoutFooter>
...
</Shell.FlyoutFooter>
</Shell>
Generally, you could override the Foreground color of the Shell to accomplish this:
<Shell
x:Class="MAUIApp1.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MAUIApp1"
FlyoutBackgroundColor="{AppThemeBinding Light=#f2f2f2, Dark=#2a2a2a}"
Shell.ForegroundColor="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}">
Alternatively, you can overwrite the style directly, by editing the Resources\Styles\styles.xaml:
<Style TargetType="Shell" ApplyToDerivedTypes="True">
<Setter Property="Shell.BackgroundColor" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource Gray950}}" />
<!--<Setter Property="Shell.ForegroundColor" Value="{OnPlatform WinUI={StaticResource Primary}, Default={StaticResource White}}" />-->
<Setter Property="Shell.ForegroundColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
</Style>

How do I change the default font of my WinUI application?

I couldn't find any guidance on Microsoft websites or on the winui github. I'm working on a WinUI 3 application, and have previously worked on WPF. I tried setting a default FontFamily for my application at the highest level using WPF methodologies, but it doesn't seem to work.
For example, in WPF I would include the FontFamily as a resource in the App.xaml.cs file.
<ResourceDictionary>
<FontFamily x:Key="MyCustomFont">pack://application:,,,/MyAssembly;component/Fonts/#CustomFontName</FontFamily
<ResourceDictionary.MergedDictionaries>
<!-- Removed for brevity -->
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Then I would set this accordingly in my Window and all textblocks etc. would change to my custom font:
<Window FontFamily="{StaticResource MyCustomFont}">
I tried to do the same in WinUI but there is no FontFamily dependency property anymore on the Window, so I'm not sure how to do it.
Any help would be greatly appreciated!
After further digging through online help, I found a strategy that worked for WinUI applications.
Add the following to your App.xaml.cs and your custom font will now be the Font that you can use as default on other UIElements such as TextBlock, TextBox, etc.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<!-- Other merged dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Other app resources here -->
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<FontFamily x:Key="MyCustomFont">ms-appx:///MyOtherAssembly/Subfolder/fontfile.ttf#MyCustomName</FontFamily>
<Style TargetType="TextBlock">
<Setter Property="FontFamily" Value="{StaticResource MyCustomFont}"/>
</Style>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Application.Resources>

Xamarin shared resources : Global Styles and Markup Extensions

Is there an advantage to using a XAML Markup Extension instead of a Style tag at the application (or page) level when setting global properties?
Context:
In the "XAML Basics" docs they give the following example:
ORIGINAL
<Button Text="Do this!"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
BorderWidth="3"
Rotation="-15"
TextColor="Red"
FontSize="24" />
... OTHER SIMILAR BUTTONS ...
CLEAN
<ContentPage.Resources>
<ResourceDictionary>
<LayoutOptions x:Key="horzOptions"
Alignment="Center" />
<LayoutOptions x:Key="vertOptions"
Alignment="Center"
Expands="True" />
<x:Double x:Key="borderWidth">
3
</x:Double>
<x:Double x:Key="rotationAngle">-15</x:Double>
</ResourceDictionary>
</ContentPage.Resources>
<Button Text="Do this!"
HorizontalOptions="{StaticResource horzOptions}"
VerticalOptions="{StaticResource vertOptions}"
BorderWidth="{StaticResource borderWidth}"
Rotation="{StaticResource rotationAngle}"
TextColor="{StaticResource textColor}"
FontSize="{StaticResource fontSize}" />
and in the docs for Style they give the following example:
RESOURCE DICTIONARY CONTAINING BUTTON STYLE set in App.cs
<Application.Resources>
<ResourceDictionary>
<Style x:Key="buttonStyle" TargetType="Button">
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
<Setter Property="BorderColor" Value="Lime" />
<Setter Property="BorderRadius" Value="5" />
<Setter Property="BorderWidth" Value="5" />
<Setter Property="WidthRequest" Value="200" />
<Setter Property="TextColor" Value="Teal" />
</Style>
</ResourceDictionary>
</Application.Resources>
BUTTON WITH STYLE APPLIED IN A ContentPage
<Button Text="These buttons" Style="{StaticResource buttonStyle}" />
Clearly they are syntactically similar but the second one is much less verbose, so what's the point of the first approach?
Obviously, they are different definitions according to the document.
XAML Markup Extensions
XAML markup extensions constitute an important feature in XAML that allow properties to be set to objects or values that are referenced indirectly from other sources. XAML markup extensions are particularly important for sharing objects, and referencing constants used throughout an application, but they find their greatest utility in data bindings.
Global Styles in Xamarin.Forms
Styles can be made available globally by adding them to the application's resource dictionary. This helps to avoid duplication of styles across pages or controls.
You will see that the range of XAML Markup Extensions is greater than Global Styles,
however Global Styles is just a special use for Styles of Resource.

What is an alternative to using RelativeSource Self?

In Xamarin Forms, I am not sure what the best alternative is for using RelativeSource Self.
For example, if I wanted a label to bind to its own Text or Tag property then in WPF I could do this:
<Style TargetType="TextBlock">
<Setter Property="Text">
<Setter.Value>
<MultiBinding Converter="{StaticResource TextConverter}">
<Binding RelativeSource="{RelativeSource Self}" Path="Tag" />
<Binding ElementName="Window" Path="DataContext.SelectedContent" />
<Binding ElementName="Window" Path="DataContext.CopyMade" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
What is the best alternative for using Xamarin.Forms?
RelativeSource is not supported in Xamarin.Forms and the usual alternative is to use Source={x:Reference} markup extension.
Depending on wether or not your Style is defined as a Resource in a ResourceDictionary, and thus can be reused, you might or might not be able to use {x:Reference} as an alternative.

Comparing two style files for if there are common x:key exist

My problem is not directly programmatic,
I'm working on a project have 5 resource dictionary . I'm not sure if same keys are used in these rd's.
i.e. rd1.xaml contains x:key="backgroundcolor" and rd2.xaml also.
In Expression Blend no error appear interestingly.
Anyway is there any of finding common keys between files?
<Application.Resources>
<ResourceDictionary>
<SolidColorBrush Color="#d0157820" x:Key="muddyBrush"/>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="rd1.xaml" />
<ResourceDictionary Source="rd2.xaml" />
<ResourceDictionary Source="rd3.xaml" />
<ResourceDictionary Source="rd4.xaml" />
<ResourceDictionary Source="rd5.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>