Page 1 of 1

MarkupExtension for multiple styles in C++

Posted: 14 Dec 2021, 13:37
by arjunc007
Hi,

I'm trying to implement a MultiStyle MarkupExtension that allows me to merge multiple Styles like
<Style x:key="Combined" BasedOn="{local:MultiStyle A B}">
      ... other properties.
</Style>
I'm, following
https://stackoverflow.com/questions/574 ... nd-basedon

The code works on the C# side but I'm having trouble using the StaticResourceExtension class to find the Style Resources in the ProvideValue function in C++.

I have this in C++ right now with a bunch of errors
Noesis::Ptr<BaseComponent> ProvideValue(const Noesis::ValueTargetProvider* provider) override {
			  Noesis::Ptr<Noesis::Style> resultStyle = *new Noesis::Style();
			  for (std::string currentResourceKey : resourceKeys)
			  {
				  Noesis::TypeClass key = Noesis::TypeClass(Noesis::Symbol(currentResourceKey.c_str()), false);
				  if (currentResourceKey == ".")
				  {
					  key = *(provider->GetTargetObject()->GetClassType());
				  }
				  Noesis::Ptr<Noesis::MarkupExtension> ext = Noesis::MakePtr<Noesis::MarkupExtension>();
				  Noesis::Style* currentStyle = Noesis::DynamicCast<Noesis::Style*>(ext->FindNodeResource(key.c_str(), true));
				  if (currentStyle == nullptr) 
					  throw std::runtime_error("Invalid Style resource specified");
				  
				  MultiStyleMethods::Merge(resultStyle, currentStyle);
			  }

			  return Noesis::Ptr<Noesis::Style>(resultStyle);
		  }
What is the right way to get resources in C++ using a string? And is making 'key' a TypeClass from a string the right approach or should it be something else?

Re: MarkupExtension for multiple styles in C++

Posted: 16 Dec 2021, 14:32
by sfernandez
Hi,

The resource keys are simple strings, you don't have to create a TypeClass for that.

Regarding the StaticResourceExtension, I see we don't have that class in the public API, could you report this in our bugtracker?
In the meantime you can just search for the resource in the target object and application resources:
Noesis::Ptr<BaseComponent> ProvideValue(const Noesis::ValueTargetProvider* provider) override {
    Noesis::Ptr<Noesis::Style> resultStyle = *new Noesis::Style();
    Noesis::ResourceDictionary* app = Noesis::GUI::GetApplicationResources();
    Noesis::IUITreeNode* node = Noesis::DynamicCast<Noesis::IUITreeNode*>(provider->GetTargetObject());
    if (node != nullptr) {
        for (std::string currentResourceKey : resourceKeys) {
            const char* key = currentResourceKey == "." ? node->GetClassType()->GetName() : currentResourceKey.c_str();
            // try find resource in the UI tree first
            Noesis::Style* currentStyle = Noesis::DynamicCast<Noesis::Style*>(node->FindNodeResource(key, false));
            if (currentStyle == nullptr) {
                // try find in application resources
                Noesis::Ptr<Noesis::BaseComponent> resource;
                if (app->Find(key, resource)) {
                    currentStyle = Noesis::DynamicCast<Noesis::Style*>(resource.GetPtr());
                    if (currentStyle == nullptr) {
                        throw std::runtime_error("Invalid Style resource specified");
                    }
                }
            }
            MultiStyleMethods::Merge(resultStyle, currentStyle);
        }
    }
    return Noesis::Ptr<Noesis::Style>(resultStyle);
}

Re: MarkupExtension for multiple styles in C++

Posted: 16 Dec 2021, 20:57
by arjunc007
Thanks for the code. This plus viewtopic.php?t=1150 worked well!

Created a bug for StaticResourceExtension here https://www.noesisengine.com/bugs/view.php?id=2216

Re: MarkupExtension for multiple styles in C++

Posted: 17 Dec 2021, 12:02
by jsantos
Thank you!