Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing Style Resources from C# - Xamarin.Forms

I'm working with a Xamarin.Forms app. the following Style I've defined in App.xaml

<Application.Resources>
    <ResourceDictionary>
        <Style x:Key="blueButton" TargetType="Button">
            <Setter Property="BackgroundColor"
                    Value="Blue" />
            <Setter Property="TextColor"
                    Value="White" />
        </Style>            
    </ResourceDictionary>
</Application.Resources>

When I want to use the Style from MainPage.xaml, it works just fine.

<Button x:Name="CreateGridButton" 
            Margin="0,15,0,0"
            Clicked="CreateGridButton_Clicked"
            Text="Create Grid Layout" Style="{StaticResource blueButton}" />

But when I want to do the same from MainPage.xaml.cs, it shows the error message "The name 'blueButton' does not exist in the Current Context".

Button createSL = new Button();
        createSL.Text = "Create Stack Layout";
        createSL.Style = (Style)Resources["blueButton"];

I also tried the following, which also showed the same error.

createSL.Style = bluebutton;

As per my requirement, I can not create this button in XAML. So kindly help me do it from Code behind.

like image 741
Imthath Avatar asked Feb 07 '18 07:02

Imthath


4 Answers

Please try to do this way

Create style in your App constructor and add this in resource like this:

public App ()
    {
        var buttonStyle = new Style (typeof(Button)) {
            Setters = {
                ...
                new Setter { Property = Button.TextColorProperty,   Value = Color.Teal }
            }
        };

        Resources = new ResourceDictionary ();
        Resources.Add ("blueButton", buttonStyle);
        ...
    }

After that use this style and set to button like this:

Button createSL = new Button();
createSL.Text = "Create Stack Layout";
createSL.Style = (Style)Application.Current.Resources ["blueButton"];
like image 175
Ziyad Godil Avatar answered Nov 10 '22 20:11

Ziyad Godil


Since you defined your style inside App.xaml:

createSL.Style = (Style)Application.Current.Resources["blueButton"];
like image 24
VahidShir Avatar answered Nov 10 '22 19:11

VahidShir


Styles can be defined at local and application level:

var buttonWithStyleFromLocalResources = button1; //button1 defined in XAML
var buttonWithStyleFromApplicationResources = button2; //button2 defined in XAML

ResourceDictionary localResourceDictionary = Resources;

//try to access local style with key "KeyForStyle"
if (localResourceDictionary.TryGetValue("KeyForStyle", out object value) && value is Style)
{
  buttonWithStyleFromLocalResources.Style = (Style)value;
}

//try to access application style with key "KeyForStyle" (from App.xaml)
ResourceDictionary applicationResourceDictionary = Application.Current.Resources;

if (applicationResourceDictionary.TryGetValue("KeyForStyle", out value) && value is Style)
{
  buttonWithStyleFromApplicationResources.Style = (Style)value;
}
like image 3
Benl Avatar answered Nov 10 '22 20:11

Benl


Context: Xamarin Forms, C#.

I developed the function GetStyleFromApplicationResource() for use in my project to load a label Style from code.

Below is a class to load the Style from a local or Application ResourceDictionary. A sample XAML and XAML.cs file is included to answer the original poster's question.

Credit to @Benl for pointing out the difference between local and Application resources.

//GenFunc.cs
namespace MyApp
{
    public static class GenFunc
    {
        public static Style GetStyleFromLocalResource(ResourceDictionary localresource, String ResourceNameKey)
        {
            if( (localresource.TryGetValue(ResourceNameKey, out Object retValue)) &&
                (retValue is Style value))
            {
                return value;
            }
            throw new Exception($"Style '{ResourceNameKey}' not found in local ResourceDictionary");
        }

        public static Style GetStyleFromApplicationResource(String ResourceNameKey)
        {
            if( (Application.Current.Resources.TryGetValue(ResourceNameKey, out Object retValue)) &&
                (retValue is Style value))
            {
                return value;
            }
            throw new Exception($"Style '{ResourceNameKey}' not found in Application ResourceDictionary");
        }
    }
}

//Test.xaml.cs
using MyApp;
using System;
using System.Reflection;
using Xamarin.Forms;

namespace MyApp.Pages
{
    public partial class Test : ContentPage
    {
        public Test()
        {
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();

            Style btnStyle = new Style(typeof(Button));

            try
            {
                lblStyle = GenFunc.GetStyleFromLocalResource(Resources, "blueButton");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            try
            {
                lblStyle = GenFunc.GetStyleFromApplicationResource("blueButton");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            Button createSL = new Button();
            createSL.Text = "Create Stack Layout";
            createSL.Style = btnStyle;

            SL0.Children.Add(createSL);
        }
    }
}

//Test.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage Title="Test"
             xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core" 
             x:Class="MyApp.Pages.Test"
             ios:Page.UseSafeArea="true">
    <ContentPage.Content>
        <StackLayout x:Name="SL0" Margin="10,0">
        </StackLayout>
    </ContentPage.Content>
</ContentPage>
like image 1
Mr_Engineer Avatar answered Nov 10 '22 18:11

Mr_Engineer