将数据传递到服务器控件中的子控件的正确模式
我正在与第三方系统合作在网站中实现某些表单。
第三方系统为我提供了这些表单的 XML 定义。 例如,
<form>
<segment>
<label>The header</label>
<fields>
...
<field>
<id>field_Dob</id>
<type>Date</type>
<label>Date of Birth</label>
<required>1</required>
</field>
...
</fields>
</segment>
...
</form>
我正在服务器控件中解析此 XML,并以编程方式生成控件树。 控件的标签在 XML 中传递。
我们建议的一部分是在这种形式中“注入”少量帮助文本。
理想情况下,我希望从顶级控件的标记中传递这些帮助文本,以便非开发人员(HTML 僧侣)可以更改帮助文本,并通过其 ID 将它们与字段相关联。 像这样的
<controls:MyCrazyForm runat="server">
<helpTexts>
<helpText for="field_Dob">
Some rambling nonsense to do with the DOB field
</helpText>
...
</helpTexts>
</controls:MyCrazyForm>
控件是递归解析的。
表单为每个段创建一个字段集,字段集根据数据类型创建许多 FieldXXX(其中 XXX = 日期、文本、组合框等)。
FieldXXX 类型创建一个 div,然后创建几个标准 .net 控件(TextBox、DropDownList 等)来实际呈现自身。 此时,我需要在包含的 div 中输出帮助文本。
我的问题
将这些文本从顶级表单控件获取到这些控件树中更深 3 或 4 层的子控件的“最佳”方法是什么。
页面上永远只会有这些表单之一。 我应该将顶级表单设置为 Singleton 并像这样得到它......?
if(MyCrazyForm.Instance.HelpTexts.ContainsKey("theIdOfTheCurrentField"))
{
this.HelpText = MyCrazyForm.Instance.HelpTexts["theIdOfTheCurrentField"];
}
我是否应该将对表单的引用传递到树中的每个控件中(这看起来很混乱)?
我的这个架构(尽管目前运行得非常好)形式是否已经离目标很远了?我应该考虑不同的实现方法吗?
谢谢
I'm working with a 3rd party system to implement some forms in a website.
The 3rd party system provides me with XML definitions for these forms.
e.g.
<form>
<segment>
<label>The header</label>
<fields>
...
<field>
<id>field_Dob</id>
<type>Date</type>
<label>Date of Birth</label>
<required>1</required>
</field>
...
</fields>
</segment>
...
</form>
I am parsing this XML in a Server Control and programatically generating a tree of controls. The labels of the controls are passed through in the XML.
It is part of our proposal to "inject" little help texts into this form.
Ideally I would like to pass these help texts in from the markup of the top level control so that non-developers (HTML monkies) can change the help texts, and associate them with the field by it's ID. Something like so
<controls:MyCrazyForm runat="server">
<helpTexts>
<helpText for="field_Dob">
Some rambling nonsense to do with the DOB field
</helpText>
...
</helpTexts>
</controls:MyCrazyForm>
The controls are parsed recursively.
The Form creates a fieldset for each segment, fieldsets create many FieldXXX (where XXX = date, text, combobox etc) depending on the data type.
The FieldXXX types create a div and then several standard .net controls (TextBox, DropDownList, etc) to actually render themselves. It is at this point, within the containing div that I need to output the help text.
My Question
What is the "best" way to get these texts from the top-level form control to these child controls which are 3 or 4 levels deeper in the control tree.
There will only ever be one of these forms on a page.
Should I make the top level form as Singleton and get it like so...?
if(MyCrazyForm.Instance.HelpTexts.ContainsKey("theIdOfTheCurrentField"))
{
this.HelpText = MyCrazyForm.Instance.HelpTexts["theIdOfTheCurrentField"];
}
Should I pass a reference to the form into every control all the way down the tree (this seems messy)?
Am I miles of target with my architecture of this (although it's working realyl nicely at the moment) form and should I look at a different method of implementation?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
一开始可能会更复杂,但更容易维护,为什么不通过 xsl 处理器运行 xml 文件呢? xslt 文件会将帮助文本文件的帮助文本节点分配给相应的字段节点。
XSLT 文件:
产生以下内容:
现在可以像以前一样解析此 xml 文件,但现在您可以在生成表单元素的同时获取帮助文本。 然后,您的 HTML 僧侣只需要编辑 XSLT 文件,或者您只需包含另一个文件:
您可以在线尝试 XSL 此处
It may be more complicated at first, but makes it easier to maintain, why not run the xml file through an xsl procesor? The xslt file would assign the helptext nodes of your helptexts file to the corresponding field nodes.
XSLT file:
yields this:
This xml file can now be parsed like before, but now you can get the help text at the same time as you are generating the form elements. Your HTML monkies then only need to edit the XSLT file, or you simply include another file :
You can try out XSL online here
正如这里的其他答案所提出的那样,除了考虑在控件之间传递信息的不同方式之外,我认为不同的方法可能是有价值的,具体取决于您的案例的具体情况。 与您所描述的问题类似的问题 - 将某些特定文本与表单上的某些控件相关联 - 已经通过资源解决了更一般的国际化情况。 我知道这与其他答案不同,也不是您在问题中直接提出的问题,但资源似乎很好地满足了需求,如下所述。 我没有回答有关控件之间信息流的具体问题,而是尝试考虑您想要实现的最终结果。 如果我误解了任何内容,请对我宽容一点:-)
As well as looking at different ways of passing information between controls, as the other answers here have put forward, I think that a different approach may be of value, depending on the specifics of your case. An analogous problem to the one you describe - associating some specific text with some controls on a form - has been solved for the more general case of internationalization, with Resources. I know this is different from the other answers and not directly what you asked in your question, but Resources seem to meet the needs quite well, as described below. Rather than answer your specific question about information flow between controls, I'm trying to consider the end result you're trying to achieve. Go easy on me if I've misunderstood anything :-)
如何向上遍历控件的父级,直到找到某种类型的控件,或者具有名为“HelpTexts”的特定成员变量?
这是一种动态编程方法,但对于设计的某些基础设施元素,只要这些方法是有限的,并且对为什么采用这种设计方法进行了很好的评论,我认为它是可以接受的。
这将使用反射 API 和通用静态辅助函数,例如
This 然后将检查 controlParent 以查看其中是否包含成员变量 HelpTexts,然后通过 id 查找帮助文本。 如果没有,它将使用 controlParent 的父级递归调用 GetHelpTextFromParent,直到出现合适的终止条件。 (我提到“合适的终止条件”,因为在到达桌面窗口之前保持这种状态可能不是最理想的,您可能希望在此之前终止递归,但这将是一个测试/调试问题。)
What about traversing upwards the parents of the control until you find a control of the certain type, or with a specific member variable called "HelpTexts"?
This is a dynamic programming approach, but for certain infrastructural elements of design, as long as such approaches are limited, as well as being well-commented as to why that design approach was taken, I'd find it acceptable.
This would be to use the reflection APIs, and a generalised static helper function, such as
This would then inspect the controlParent to see if it had the member variable HelpTexts within it, and then look up by id the helptext. If not, it would recursively call GetHelpTextFromParent with the parent of controlParent, until a suitable terminating condition. (I mention "suitable terminating condition" because it is probably suboptimal to keep this up until you get to the desktop window, you may want to terminate the recursion prior to then, but this would be a testing/debugging issue.)
如果您在服务器控件中解析此 XML 并以编程方式生成控件树,您如何确保 HTML 人员保持这些 ID 同步? 如果他们有权访问这些 XML,也许您应该让他们在此处添加帮助文本,而不是在 aspx 上。
但为了回答你的问题,我想你在读取和构建 aspx 标记之后解析 xml,这样你就可以在解析 XML 之前对这些文本建立索引。 然后,当您实际构建动态控件树时,您可以通过源 xml 中定义的控件 id 查找索引,并在此时将其连接起来。
编辑:好的,根据您构建这些子控件的方式,我将在内部公开表单的所有内联帮助文本作为由控件 id 索引的属性,这将为您提供帮助文本或空字符串。 但我不确定我是否得到了MyCrazyForm.Instance。
If you're parsing this XML in a Server Control and programatically generating a tree of controls how do you make sure the HTML guys keep those IDs in sync? If they have access to those XMLs maybe you should let them add helpTexts right there and not on the aspx.
But to answer your question, I suppose you're parsing the xml after the aspx markup was read and built so you could index those texts right before parsing the XML. Then when you actually build your dynamic control tree you look up your index by the control's id defined in you source xml and hook it up at this point.
EDIT: Okay, depending on how you build those child controls, I'd expose all of those inline helptexts of the form internally as a property indexed by the control id which would give you the help text or an empty string. I'm not sure I get the MyCrazyForm.Instance though.
我建议创建一个像这样的接口
然后您的表单控件可以实现这个接口并在创建字段集和FieldXXX控件时传递对此接口的引用。
或者,您可以按照多语言建议进行操作,当需要帮助文本时,FieldXXX 控件会递归地遍历其父级,直到找到实现 IHelpTextProvider 接口的父级。
I suggest to create an interface like this
Then your form control can implement this interface and pass a reference to this interface when creating fieldsets and FieldXXX controls.
Alternatively, you can do as polyglot suggested and when help text is needed, FieldXXX control go recursively through its parents until a parent implementing IHelpTextProvider interface is found.
您可以在服务器控件中创建一个事件,只要它想要/需要给定字段的帮助文本,就会引发该事件。 该表单可以连接事件处理程序并对其做出响应。 这样,您就不需要传递某些对象来让服务器控制对信息的访问。 为此,我们需要做三件事。
创建一个 EventArgs 类:
在服务器控件中创建事件:
...并在可以访问帮助文本的表单中设置事件处理程序:
使用此方法,即使托管表单不提供帮助,代码也可以正常工作短信服务; 服务器控件不依赖于附加的事件处理程序这一事实。
You could create an event in the server control that it would be raised whenever it wants/needs a help text for a given field. The form can hook up an event handler and respond to it. That way you don't need to pass around some object to give the server control access to the information. For this we need to do three things.
Create an EventArgs class:
Create the event in the server control:
...and set up an event handler in the form that can access the help texts:
Using this approach the code will work fine even if the hosting form does not provide the help text service; the server control is not depending on the fact that there is an event handler attached.
正如 Ozam 所建议的,您可以使用 XSL。
一个单独的 XML 文件,其结构与第 3 方 xml 文件的结构类似,其中每个 XML 节点包含 helpText,这将是很好的选择。 你可能需要以某种方式合并(?)它们。
我根本不知道这是否有任何帮助。
As Ozam suggested, you could use XSL.
A separate XML file with the similar structure as that of the 3rd party xml file which contains helpText per XML node would be good & you might need to merge(?) them in some way.
I dont know if this help in any way, at all.