Search code examples
.netcastle-monorail

Render ViewComponent from another component codebehind


I'm trying to render a component from withing another component.

public override void Render()
// ...
    var block = new Block();
    block.Init(EngineContext, Context);
    block.Render();
// ...
}

The problem is that Block component can't find it's template.

ResourceProcessingException Message: Unable to process resource 'components\CustomReportComponentComponent\default.vm': Resource could not be located

I guess, other problems can arise because the component is not properly initialized.

Is it possible to initialize a component from within another component's Render method, so it renders just as if called from a .vm?


Solution

  • I think you need to call .Init with a new IViewComponentContext.

      component.Init(EngineContext, newViewComponentContext);
    

    now the implementations for IViewComponentContext are within the various view engines. The problem is - I am not familiar with NVelocity's internals so I can't be sure about the way to do that with NV, you'd need a follow up question.

    A possible workaround: You can have a shared view template, that calls a component, whose name is passed to the view as a parameter.

    In AspView it would look something like:

    // in the calling component
    PropertyBag["componentName"] = "theOtherComponent";
    PropertyBag["componentParams"] = new Hashtable{{age,30},{name,"Ken"}};
    var componentOutput = RenderViewInPlace("/shared/render_component");
    
    
    // in render_component.aspx
    <% InvokeViewComponent(Properties["componentName"], Properties["componentParams"], null, null); %>
    

    This approach should work in theory, assuming NV can get a parameter for #blockcomponent (again - another follow up question is needed, sorry )