Sitecore WFFM覆盖在演示文稿详细信息中选择的FormID

Sitecore WFFM覆盖在演示文稿详细信息中选择的FormID,sitecore,web-forms-for-marketers,Sitecore,Web Forms For Marketers,在特定场景中,我需要以编程方式更改表单呈现器中显示的WFFM表单。表单呈现程序本身通过“表示详细信息”添加到占位符中 我可以访问表单渲染并设置FormID,并将其参数更新为我要显示的表单的ID。然而,即使我在页面生命周期的早期移动代码(例如page_Init),Sitecore似乎也不尊重这些属性并显示原始表单。我的代码如下 //子布局的传入控件 公共FormRender SetFormRender(控件,字符串数据源) { FormRender FormRender=null; //通过传入控

在特定场景中,我需要以编程方式更改表单呈现器中显示的WFFM表单。表单呈现程序本身通过“表示详细信息”添加到占位符中

我可以访问表单渲染并设置FormID,并将其参数更新为我要显示的表单的ID。然而,即使我在页面生命周期的早期移动代码(例如page_Init),Sitecore似乎也不尊重这些属性并显示原始表单。我的代码如下

//子布局的传入控件
公共FormRender SetFormRender(控件,字符串数据源)
{
FormRender FormRender=null;
//通过传入控件中包含的控件进行循环
foreach(Control.Controls中的控件子级)
{
if(子级为FormRender)
{
formRender=作为formRender的子级;
如果(formRender!=null)
{
formRender.FormID=数据源;
formRender.Parameters=“FormID=“+HttpUtility.HtmlEncode(数据源);
打破
}
}
//如果控件具有传递给此方法进行递归的控件
if(control.HasControls())
{
var nestedFormRender=SetFormRender(子级,数据源);
if(nestedFormRender!=null&&formRender==null)
{
formRender=嵌套的formRender;
打破
}
}
}
返回formRender;
}

这是因为当表单添加到控件集合时,它实际上是呈现的。如果必须遵循此体系结构,我的建议是从集合中删除控件,然后通过

control.Controls.Add(formRender);

效率不是很高,但应该可以工作。

可能在设置FormID和参数后,您需要调用FormRender.OnInit(),因此您的代码可能如下所示:

。。。。
formRender.FormID=数据源;
formRender.Parameters=“FormID=“+HttpUtility.HtmlEncode(数据源);
formRender.OnInit(空);
打破
....
编辑

我不认为您可以从代码中调用formRender.OnInit()作为其受保护的方法,但您可以做的是创建一个继承formRender的新控件,并用它替换presentation details上的控件,然后重写OnInit()方法并放置处理FormID属性的代码,然后调用base.OnInit()


Mike Reynolds有一个关于如何基于查询字符串加载不同表单的博客

我发现了一个基于Ahmed Okur建议的解决方案,使我实现了50%的目标,但需要额外的工作

我创建了一个新的FormRender,它为要传递的重写表单Id公开了一个公共属性。这个新的FormRender实现了现有的方法,但是重写基OnInit()仍然会生成一个受保护的方法,这意味着在需要时无法调用它。因此,我创建了一个非重写的public OnInit()方法:

公共类PublicFormRender:FormRender
{
公共字符串重写formid{get;set;}
公共无效OnInit()
{
OnInit(新事件参数());
}
受保护的覆盖无效OnInit(System.EventArgs e)
{
//此处添加了新逻辑,因此始终遵循覆盖Id
//尤其是在通过前端添加PublicFormRender的情况下
如果(!string.IsNullOrEmpty(重写FormID))
{
FormID=覆盖FormID;
var parameters=WebUtil.ParseUrlParameters(参数);
if(参数[“FormID”]!=null)
参数[“FormID”]=HttpUtility.HtmlEncode(覆盖FormID);
Parameters=Parameters.ToString();
}
碱基.奥尼特(e);
}
}
我在路径
/Sitecore/layout/Renderings/Modules/webforms for Marketers/
复制了Sitecore中的FormRender,引用了
PublicFormRender
,并使用它在演示细节中添加表单

publicPublicIDFormRender SetFormRender(控件控件,字符串数据源)
{
PublicIdFormRender formRender=null;
//循环查找新的PublicFormRender
foreach(Control.Controls中的控件子级)
{
var publicFormRender=作为publicFormRender的子级;
if(publicFormRender!=null)
{
//将新公共属性设置为数据源
publicFormRender.OverridingFormId=数据源;
//通过非重写公共方法初始化表单
publicFormRender.OnInit();
formRender=publicFormRender;
打破
}
if(control.HasControls())
{
var nestedFormRender=SetFormRender(子级,数据源);
if(nestedFormRender!=null&&formRender==null)
{
formRender=嵌套的formRender;
打破
}
}
}
返回formRender;
}

您是否尝试过设置
formRender.DataSource=DataSource
?WFFM的较新版本有所改变,因此使用了数据源值,至少对于MVC是这样,对于WebForms也是这样
FormRender.FormID
还将首先检查数据源值,否则将使用
GetRender()
中设置的FormID,这可能太晚了,因为控件已经初始化。您正确地认为OnInit()是受保护的方法。我认为下一种方法是创建一个实现FormRender的控件。我也要看看迈克的博客。你的编辑让我找到了解决问题的绝大部分方法——谢谢你的帮助