Frage

Ich habe die Einrichtung einen User Control auf einer XML-Konfiguration angetrieben. Es ist einfacher, mit gutem Beispiel zu erklären. Werfen Sie einen Blick auf die folgende Konfiguration Snippet:

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

Was ich versuche, dass die Schnipsel in einem einzigen Textfeld und eine Checkbox-Steuerung zu erreichen zu übersetzen. Natürlich hatte automatisch würde das Snippet enthalten mehr Knoten mehr Kontrollen erzeugt wird.

Geben Sie die iterative Natur der Aufgabe, habe ich gewählt, Repeater zu verwenden. In ihm habe ich zwei platziert (auch mehr, siehe unten) Controls, ein CheckBox und ein Editbox. Um zu entscheiden, welche aktivieren kontrollieren, benutzen ich einen Inline-Schaltbefehl, den Namen des aktuellen Konfigurationsknoten zu überprüfen.

Leider, das funktioniert nicht. Das Problem liegt in der Tatsache, dass der Schalter während der Wiedergabe Zeit ausgeführt wird, lange nachdem die Daten geschehen waren Bindung. Das allein kein Problem sein würde, war nicht die Tatsache, dass ein Konfigurationsknoten könnte die benötigten Informationen, um Daten binden bieten. Überlegen Sie, was passieren würde, wenn das Kontrollkästchen Kontrolle wird versuchen, oben auf den Textknoten im Snippet zu binden, verzweifelt auf der Suche nach es ist „geprüft“ Attribut.

Alle Ideen, wie dies möglich zu machen?

Danke, Boaz

Hier ist mein aktueller Code:

Hier ist mein Code (die als die auf einer komplexeren Syntax läuft oben):

<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>
War es hilfreich?

Lösung

Ein Wochenende später, hier ist das, was ich mit so einer Lösung kam. Mein Hauptziel war es, etwas zu finden, die beide arbeiten und ermöglichen es Ihnen den genauen Inhalt der Elementvorlage in Markup zu halten angeben. funktionieren würde, Dinge aus dem Code tun kann, aber immer noch umständlich sein.

Der Code sollte einfach sein zu folgen, aber der Kern der Sache liegt in zwei Teilen.

Die erste ist die Verwendung des Repeaters Artikel erstellt Ereignis unerwünschte Teile der Vorlage auszufiltern.

Die zweite ist, Entscheidungen in Viewstate gemacht zu speichern, um die Seite während der Post zurück zu erstellen. Die später ist von entscheidender Bedeutung, wie Sie feststellen, dass ich die Item.DataItem verwendet. Während der Post Rücken steuern Erholung viel früher im Lebenszyklus der Seite passiert. Wenn die ItemCreate Brände, die DataItem ist null.

Hier ist meine Lösung:

Steuer Markup

 <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>

. Hinweis: für zusätzliche Leichtigkeit ich hinzugefügt, um das Placeholder-Steuerelement zu gruppieren Dinge und die Entscheidung treffen, von denen kontrolliert leichter entfernen

Code hinter

Der Code unten auf der Vorstellung aufgebaut, dass jeder Repeater ein Element eines Typs ist. Die Art wird aus der XML-Konfigurations extrahiert. In meinem speziellen Szenario könnte ich diese Art zu einer einzigen Steuerung mittels ID machen. Dies könnte leicht geändert werden, wenn nötig.

 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);
      }
   }

Andere Tipps

Sie brauchen etwas, das mehr wie folgt aussieht:

<ItemTemplate>
    <%# GetContent(Page.GetDataItem()) %>
</ItemTemplate>

Und dann haben alle Steuerelemente in der Code-Behind erzeugt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top