1

I have a static class with statically defined HEX values of colors:

namespace Namespace1
{
    public static class MyColors
    {
        public const string COLOR_1 = "#AABBCC";
        // ...
    }
}

I want to have all these colors defined in a resource dictionary so that they can be used in XAML:

<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="Namespace2.Style.Colors"
    xmlns:n1="clr-namespace:Namespace1;assembly=Assembly1">
    <Color x:Key="Color1" x:FactoryMethod="FromHex">
        <x:Arguments>
            <x:String>{x:Static n1:MyColors.COLOR_1}</x:String>
        </x:Arguments>
    </Color>
    <!-- ... -->
</ResourceDictionary>

But this doesn't seem to work. There is no compile error, but the color itself is empty (transparent).

If I replace the {x:Static n1:MyColors.COLOR_1} part with the actual #AABBCC value, then it works.

I have also tested the {x:Static n1:MyColors.COLOR_1} part (with Label and Text property) and it works.

So what is the problem here? This seems like an internal Xamarin.Forms bug.

GregorMohorko
  • 2,739
  • 2
  • 22
  • 33
  • why do you need to define the color on the class. I would define it in the xaml... – Marco Feb 03 '18 at 19:20
  • Because the color constants are defined in a common .NETStandard 2.0 assembly and is referenced by WPF applications too, not only Xamarin.Forms. – GregorMohorko Feb 03 '18 at 19:21
  • Can you define both? The value as string and the value as Color? Something like this: https://stackoverflow.com/questions/10062376/creating-solidcolorbrush-from-hex-color-value – Marco Feb 03 '18 at 19:38
  • 1
    I think it's not possible to do the way you want. It has been asked before. https://forums.xamarin.com/discussion/65684/setting-color-in-xaml-from-hex-string-declared-in-code – Marco Feb 03 '18 at 19:39
  • Wow, I haven't found this discussion on the forum. So what is the alternative? Can I define the actual color in code and then statically reference it in XAML? – GregorMohorko Feb 03 '18 at 19:41
  • You should create a custom type converter, more info here: https://msdn.microsoft.com/es-es/library/ee126043(v=vs.110).aspx – Gusman Feb 03 '18 at 19:54
  • Here is an older answer: https://stackoverflow.com/a/12155892/3346583 But it strongly depends on the specific color structure/class you need. A simple Converter (string to XAML Color) should be usefull. – Christopher Feb 03 '18 at 20:13
  • @Gusman And how do I then use that converter to define a color? I know how to create a type converter, I just don't know how to use it in this case. – GregorMohorko Feb 03 '18 at 20:35

4 Answers4

2

The problem itself was not solved, but the solution for what I was trying to achieve was found:

So, instead of declaring the colors in the Colors.xaml file, it is possible to declare them in the Colors.xaml.cs file instead, using the Add method:

namespace Namespace2.Style
{
    public partial class Colors : ResourceDictionary
    {
        public Colors()
        {
            InitializeComponent();

            Add("Color1", Color.FromHex(MyColors.COLOR_1));
            // ...
        }
    }
}
GregorMohorko
  • 2,739
  • 2
  • 22
  • 33
1

Well, forget about the type converter. I got it working like this:

<SolidColorBrush x:Key="Color1" Color="{Binding Source={x:Static n1:MyColors.COLOR_1}}" />

Is this an alternative for you?

Marco
  • 984
  • 10
  • 18
1

Classes in an assembly named MyAssembly:

namespace MyNamespace
{
  public static class MyColors
  {
    public const string Blue = "#AABBCC";
  }

  public static class MyColor
  {
    public static Color MyBlue { get { return Color.FromHex(MyColors.Blue); } }
  }
}

XAML:

xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:c="clr-namespace:MyNamespace;assembly=MyAssembly"
...
<Label Text="MyColor.MyBlue example" TextColor="{x:Static c:MyColor.MyBlue}"/>

Please note that the c namespace might be named e.g. myColor to better identify it. The notation in the Label would then be myColor:MyColor.MyBlue.

Benl
  • 2,777
  • 9
  • 13
  • This works, but I prefer my solution, where I can simply then use the colors as `StaticResource` without having to import a namespace etc.. – GregorMohorko Feb 09 '18 at 22:55
0

If you have the time to test the solution with a type converter:

namespace Namespace1
{
    using System.ComponentModel;
    using System.Windows.Media;

    public static class MyColors
    {
        [TypeConverter(typeof(ColorConverter))]
        public static string COLOR_1 { get; } = "#AABBCC";
    }
}
Marco
  • 984
  • 10
  • 18
  • And how do I now use this to define the color in XAML? Doing only this does nothing. – GregorMohorko Feb 03 '18 at 21:16
  • Well, it should have work automatically with the original code. So I will need to try it myself and check why the converter is not called in this case. I will get back to you if i get it working. I'm curious now ;-) – Marco Feb 03 '18 at 21:19
  • It expects a string, not a Color. The converter is used when you are using this string field and the color is expected. But like I said, in this case, a string is expected. – GregorMohorko Feb 03 '18 at 21:25