gpt4 book ai didi

c# - 如何在数据绑定(bind)转发器中创建条件内容

转载 作者:太空狗 更新时间:2023-10-30 01:12:29 25 4
gpt4 key购买 nike

我正在设置一个由 XML 配置驱动的用户控件。通过示例更容易解释。看看下面的配置片段:

<node>
<text lbl="Text:"/>
<checkbox lbl="Check me:" checked="true"/>
</node>

我想要实现的目标是将该片段转换为单个文本框和复选框控件。当然,如果代码片段包含更多节点,则会自动生成更多控件。

鉴于任务的迭代性,我选择使用Repeater。我在其中放置了两个(还有更多,请参见下文)控件,一个 CheckBox 和一个 Editbox。为了选择激活哪个控件,我使用了内联切换命令,检查当前配置节点的名称。

遗憾的是,这不起作用。问题在于开关是在渲染期间运行的,在数据​​绑定(bind)发生很久之后。仅此一点不会成为问题,并不是因为配置节点可能会提供数据绑定(bind)所需的信息。考虑一下如果复选框控件尝试绑定(bind)到上面代码片段中的文本节点,拼命寻找它的“选中”属性,会发生什么情况。

有什么想法可以实现吗?

谢谢,波阿斯

这是我当前的代码:

这是我的代码(它运行的语法比上面的更复杂):

<asp:Repeater ID="settingRepeater" runat="server">
<ItemTemplate>
<%
switch (((XmlNode)Page.GetDataItem()).LocalName)
{
case "text":
%>
<asp:Label ID="settingsLabel" CssClass="editlabel" Text='<%# XPath("@lbl") %>' runat="server" />
<asp:TextBox ID="settingsLabelText" Text='<%# SettingsNode.SelectSingleNode(XPath("@xpath").ToString()).InnerText %>'
runat="server" AutoPostBack="true" Columns='<%# XmlUtils.OptReadInt((XmlNode)Page.GetDataItem(),"@width",20) %>'
/>
<% break;
case "checkbox":
%>
<asp:CheckBox ID="settingsCheckBox" Text='<%# XPath("@lbl") %>' runat="server"
Checked='<%# ((XmlElement)SettingsNode.SelectSingleNode(XPath("@xpath").ToString())).HasAttribute(XPath("@att").ToString()) %>'
/>
<% break;
} %>
&nbsp;&nbsp;
</ItemTemplate>
</asp:Repeater>

最佳答案

一个周末后,这是我提出的解决方案。我的主要目标是找到既可以工作又可以让您在标记中继续指定项目模板的确切内容的东西。从代码中做事是可行的,但仍然很麻烦。

代码应该很容易理解,但问题的要点分为两部分。

首先是使用 Repeater item created 事件来过滤掉模板中不需要的部分。

第二个是存储在 ViewState 中做出的决定,以便在回发期间重新创建页面。后者至关重要,因为您会注意到我使用了 Item.DataItem 。在回发期间,控件重新创建发生在页面生命周期的早期。当 ItemCreate 触发时,DataItem 为空。

这是我的解决方案:

控制标记

 <asp:Repeater ID="settingRepeater" runat="server" 
onitemcreated="settingRepeater_ItemCreated"
>
<ItemTemplate>
<asp:PlaceHolder ID="text" runat="server">
<asp:Label ID="settingsLabel" CssClass="editlabel" Text='<%# XPath("@lbl") %>' runat="server" />
<asp:TextBox ID="settingsLabelText" runat="server"
Text='<%# SettingsNode.SelectSingleNode(XPath("@xpath").ToString()).InnerText %>'
Columns='<%# XmlUtils.OptReadInt((XmlNode)Page.GetDataItem(),"@width",20) %>'

/>

</asp:PlaceHolder>
<asp:PlaceHolder ID="att_adder" runat="server">
<asp:CheckBox ID="settingsAttAdder" Text='<%# XPath("@lbl") %>' runat="server"
Checked='<%# ((XmlElement)SettingsNode.SelectSingleNode(XPath("@xpath").ToString())).HasAttribute(XPath("@att").ToString()) %>'
/>
</asp:PlaceHolder>
</ItemTemplate>
</asp:Repeater>

注意:为了更加轻松,我添加了 PlaceHolder 控件来对事物进行分组,并更轻松地决定要删除哪些控件。

代码隐藏

下面的代码是建立在每个转发器项目都是一个类型的概念之上的。该类型是从配置 xml 中提取的。在我的特定场景中,我可以通过 ID 将该类型制作为单个控件。如果需要,这可以很容易地修改。

 protected List<string> repeaterItemTypes
{
get
{
List<string> ret = (List<string>)ViewState["repeaterItemTypes"];
if (ret == null)
{
ret = new List<string>();
ViewState["repeaterItemTypes"] = ret;
}
return ret;
}
}

protected void settingRepeater_ItemCreated(object sender, RepeaterItemEventArgs e)
{
string type;
if (e.Item.DataItem != null)
{
// data binding mode..
type = ((XmlNode)e.Item.DataItem).LocalName;
int i = e.Item.ItemIndex;
if (i == repeaterItemTypes.Count)
repeaterItemTypes.Add(type);
else
repeaterItemTypes.Insert(e.Item.ItemIndex, type);
}
else
{
// restoring from ViewState
type = repeaterItemTypes[e.Item.ItemIndex];
}

for (int i = e.Item.Controls.Count - 1; i >= 0; i--)
{
if (e.Item.Controls[i].ID != type) e.Item.Controls.RemoveAt(i);
}
}

关于c# - 如何在数据绑定(bind)转发器中创建条件内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/274056/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com