Dynamic resources vs Binding

raV720raV720 PLMember ✭✭

I am wondering how to use dynamic resource in real world application.
Dynamic resources seems useful when defining dynamic styles for application (font size, colors etc..) and this styles are dynamic - it is possible to change the style during application runtime and changes will take effect (in opposite to static resources). However I do not know how to provide dynamic resource dictionary to View, because ViewModel actually does not have access to View. I can do it via ViewModel but using Binding.

So how to use Dynamic Resources?

Answers

  • raV720raV720 PLMember ✭✭

    How behaviors can help with using Dynamic Resources?

  • WinterCloudWinterCloud GBMember ✭✭✭

    you can bind views visibility to achieve that.

    However, this is not WPF, so a bit waste resource if there are a lot of changes. I'd suggest a different page if there are a lot of difference.

    Also, when I tried change theme dynamically, ie background color, app always crash, I'm only on Android, so don't know how ios behave.

    So, be aware.

  • raV720raV720 PLMember ✭✭

    you can bind views visibility to achieve that

    What you mean?

  • WinterCloudWinterCloud GBMember ✭✭✭

    @raV720 said:

    you can bind views visibility to achieve that

    What you mean?

    You put all views you needed in one page, and bind each view's visibility to control if you want to show them or not.

  • raV720raV720 PLMember ✭✭

    You put all views you needed in one page, and bind each view's visibility to control if you want to show them or not.

    How does it relate to Dynamic Resources?
    I am asking how to attach DynamicResource to View during application runtime.

  • WinterCloudWinterCloud GBMember ✭✭✭

    @raV720 said:

    You put all views you needed in one page, and bind each view's visibility to control if you want to show them or not.

    How does it relate to Dynamic Resources?
    I am asking how to attach DynamicResource to View during application runtime.

    Ok, I misunderstood you, I thought you want to dynamically change page contents.

    The word didn't click because I personally don't use them, and don't believe DynamicResource is the right approach. I use MVVM binding, suit me better. If you have to use DynamicResource, suggest you have a look this thread first, examples and issues in there.

    https://forums.xamarin.com/discussion/65252/dynamicresource-limitation-for-onplatform-in-xaml-xamarin-forms

  • raV720raV720 PLMember ✭✭

    Thanks, I saw this link before.

    Yeah, I haven't seen any example using DynamicResource.
    I think I will try to inject resources to View during View resolving. It seems right way.

  • aspnerd007aspnerd007 Member ✭✭
    edited May 2018

    @raV720 I finally figured out a solution as I needed one myself. Let me know if this works for you.

    I have a MenuItemTemplate which is used as data template, and in that I have a label. Note the style binding.
    <Label x:Name="LabelIcon" HorizontalOptions="Start" Text="{ Binding Icon }" Style="{Binding IconType , Converter={ StaticResource ConvertStyleKey }}" VerticalTextAlignment="Center" AbsoluteLayout.LayoutBounds="0, 0.5, 20, 1" AbsoluteLayout.LayoutFlags="XProportional, YProportional, HeightProportional" />
    The Binding IconType is a bool value.

    I added this to the contentview at the top: xmlns:local="clr-namespace:MyApp.Mobile;assembly=MyApp.Mobile"

    Then this:

    <ContentPage.Resources> <ResourceDictionary> <local:ConvertStyle x:Key="ConvertStyleKey" /> </ResourceDictionary> </ContentPage.Resources>

    Now in the code behind of the template and below the contentview page class I added a new class

    `
    public class ConvertStyle : IValueConverter
    {
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
    bool IconType = false;
    try
    {
    IconType = (bool)value;
    }
    catch (Exception ex)
    {

            }
            if (IconType)
            {
                return Application.Current.Resources["MainMenuIconStyle1"] as Style;
            }
            else
            {
                return Application.Current.Resources["MainMenuIconStyle2"] as Style;
            }
        }
    }
    

    `

    It grabs the binding of IconType, then returns the static resource as a style. My static style is in my app.xml

    `





            <Style
                x:Key="MainMenuIconStyle2"
                TargetType="Label">
                <Setter
                    Property="TextColor"
                    Value="{ DynamicResource MainMenuIconColor }" />
                <Setter
                    Property="FontFamily"
                    Value="{ StaticResource CustomFontFamily }" />
                <Setter
                    Property="FontSize"
                    Value="{ StaticResource MainMenuIconFontsize }" />
                <Setter
                    Property="VerticalOptions"
                    Value="CenterAndExpand" />
            </Style>
    

    `

  • aspnerd007aspnerd007 Member ✭✭
    edited May 2018

    Hi @raV720 ...I had a need to change a style based on a value of an individual record. I was not able to find a solution, but I played with several ideas I saw online and came up with this solution.

    I have a MenuItemTemplate which is used in a datatemplate for a listview.

    At the top of the page I added this attribute in the ContentView tag

    xmlns:local="clr-namespace:MyApp.Mobile;assembly=MyApp.Mobile"

    I then added this as a local resource:

    <ContentPage.Resources> <ResourceDictionary> <local:ConvertStyle x:Key="ConvertStyleKey" /> </ResourceDictionary> </ContentPage.Resources>

    Then in my page I have my label I'm dynamically changing the style to a static resource based on a boolean value per record.

    <Label x:Name="LabelIcon" HorizontalOptions="Start" Text="{ Binding Icon }" Style="{Binding IconType , Converter={ StaticResource ConvertStyleKey }}" VerticalTextAlignment="Center" AbsoluteLayout.LayoutBounds="0, 0.5, 20, 1" AbsoluteLayout.LayoutFlags="XProportional, YProportional, HeightProportional" />

    Now in the MenuItemTemplate code behind, below the ContentView class I added a new class.

    `public class ConvertStyle : IValueConverter
    {
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
    bool IconType = false;
    try
    {
    IconType = (bool)value;
    }
    catch (Exception ex)
    {

            }
            if (IconType)
            {
                return Application.Current.Resources["MainMenuIconStyle1"] as Style;
            }
            else
            {
                return Application.Current.Resources["MainMenuIconStyle2"] as Style;
            }
        }
    }
    

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
    // You probably don't need this, this is used to convert the other way around
    // so from color to yes no or maybe
    throw new NotImplementedException();
    }`

    Now in my app.xml here are my static resource styles:

    `




            <Style
                x:Key="MainMenuIconStyle2"
                TargetType="Label">
                <Setter
                    Property="TextColor"
                    Value="{ DynamicResource MainMenuIconColor }" />
                <Setter
                    Property="FontFamily"
                    Value="{ StaticResource CustomFontFamily }" />
                <Setter
                    Property="FontSize"
                    Value="{ StaticResource MainMenuIconFontsize }" />
                <Setter
                    Property="VerticalOptions"
                    Value="CenterAndExpand" />
            </Style>`
    

    Let me know if this works for you.

  • raV720raV720 PLMember ✭✭

    @aspnerd007 what you described is not an use of DynamicResources. You just refer dynamically to StaticResources.

Sign In or Register to comment.