JakeBungarrra
Topic Author
Posts: 9
Joined: 11 Jul 2019, 03:32

Loading ResourceDirectorys on runtime.

19 Jul 2019, 05:02

What im attempting to do is have XAML files load a resource directory from start, based on an if statement.
For example, I have 2 resource directories, blue and red, both with the same key "buttonColor". with different colour brushes.
What I want to do is check on runtime through a script, if the blueBool = true, then load the blue resource directory, if redBool = true load the red ResourceDirectory.
is this the correct method that I should be using to do so, or is there a different method to get a similar result. that can done through the Xaml files themselves.

Tags:
 
User avatar
sfernandez
Site Admin
Posts: 1911
Joined: 22 Dec 2011, 19:20

Re: Loading ResourceDirectorys on runtime.

22 Jul 2019, 17:35

You can load a dictionary xaml file by calling Noesis::GUI::LoadXaml(), and set that dictionary as the Resources of any FrameworkElement in the UI tree.
Ptr<Noesis::ResourceDictionary> dictA = Noesis::GUI::LoadXaml<Noesis::ResourceDictionary>("DictA.xaml");
rootElement->SetResources(dictA);
If you are building your application using MVVM pattern, you can create an interactivity action that encapsulates that code:
class SetResourcesAction: public NoesisApp::TriggerActionT<Noesis::FrameworkElement>
{
public:
    const Noesis::Uri& GetSource() const { return GetValue<Noesis::Uri>(SourceProperty); }
    void SetSource(const Noesis::Uri& value) { SetValue<Noesis::Uri>(SourceProperty, value); }

    static const Noesis::DependencyProperty* SourceProperty;

private:
    Noesis::Ptr<Noesis::Freezable> CreateInstanceCore() const override
    {
        return Noesis::MakePtr<SetResourcesAction>();
    }

    void Invoke(Noesis::BaseComponent* parameter) override
    {
        Noesis::FrameworkElement* element = GetAssociatedObject();
        element->SetResources(mResources);
    }

    static void OnSourceChanged(Noesis::DependencyObject* d,
        const Noesis::DependencyPropertyChangedEventArgs& e)
    {
        SetResourcesAction* action = (SetResourcesAction*)d;
        const Uri& source = *((const Uri*)e.newValue);
        action->mResources = Noesis::GUI::LoadXaml<Noesis::ResourceDictionary>(source.Get());
    }

    Noesis::Ptr<Noesis::ResourceDictionary> mResources;

    NS_IMPLEMENT_INLINE_REFLECTION(SetResourcesAction,
        NoesisApp::TriggerActionT<Noesis::FrameworkElement>)
    {
        NsMeta<Noesis::TypeId>("MyNamespace.SetResourcesAction");

        Noesis::DependencyData* data =
            NsMeta<Noesis::DependencyData>(Noesis::TypeOf<SetResourcesAction>());

        data->RegisterProperty<Noesis::Uri>(SourceProperty, "Source",
            Noesis::PropertyMetadata::Create(Noesis::Uri(""), &OnSourceChanged));
    }
};

const Noesis::DependencyProperty* SetResourcesAction::SourceProperty;
So you can reuse it in the xaml:
<UserControl
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
  xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
  xmlns:local="clr-namespace:MyNamespace">
  
  <Grid x:Name="LayoutRoot">
    <i:Interaction.Triggers>
      <ei:DataTrigger Binding="{Binding IsBlue}" Value="True">
        <local:SetResourcesAction Source="BlueResources.xaml" />
      </ei:DataTrigger>
      <ei:DataTrigger Binding="{Binding IsRed}" Value="True">
        <local:SetResourcesAction Source="RedResources.xaml" />
      </ei:DataTrigger>
    </i:Interaction.Triggers>
    ...
  </Grid>
</UserControl>
Hope this helps.
 
JakeBungarrra
Topic Author
Posts: 9
Joined: 11 Jul 2019, 03:32

Re: Loading ResourceDirectorys on runtime.

25 Jul 2019, 03:22

This does look like what I need exactly, is it possible to get the c# version?.
 
User avatar
sfernandez
Site Admin
Posts: 1911
Joined: 22 Dec 2011, 19:20

Re: Loading ResourceDirectorys on runtime.

25 Jul 2019, 14:12

In C# the code for the trigger action will look like this:
using System;

public MyNamespace
{
    public class SetResourcesAction : NoesisApp.TriggerAction<Noesis.FrameworkElement>
    {
        public Uri Source
        {
            get { return (Uri)GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); }
        }

        static readonly Noesis.DependencyProperty SourceProperty = Noesis.DependencyProperty.RegisterProperty(
            "Source", typeof(Uri), typeof(SetResourcesAction),
            new Noesis.PropertyMetadata(null, OnSourceChanged));

        static void OnSourceChanged(Noesis.DependencyObject d, Noesis.DependencyPropertyChangedEventArgs e)
        {
            SetResourcesAction action = (SetResourcesAction)d;
            Uri source = (Uri)e.NewValue;
            if (source != null)
            {
                action._resources = (Noesis.ResourceDictionary)Noesis.GUI.LoadXaml(source.ToString());
            }
            else
            {
                action._resources = null;
            }
        }

        protected override void Invoke(object parameter)
        {
            Noesis.FrameworkElement element = AssociatedObject;
            element.Resources = _resources;
        }

        private ResourceDictionary _resources;
    }
}

Who is online

Users browsing this forum: No registered users and 1 guest