2016-07-01 4 views
-1

Ich habe ein bisschen eine Situation. Ich bin neu zu asp aber alter Hut mit .net winforms. Ich erstelle derzeit ASP-Seiten dynamisch. Kürzlich wurde ich gebeten, ein Filter-Dropdown in eine Spaltenüberschrift einzufügen. Also habe ich eine Methode erstellt, die die Vorlage und die Spalte generiert und das Label für den Namen und das Drop-Down-Element hinzufügt. Keine große Sache. Ursprünglich konnte ich das Ereignis nicht erhöhen, also setze ich es auf AutoPostBack = true und das Ereignis wurde ausgelöst, aber der Wert wird nicht beibehalten.DropDownList in GridView Header nicht beibehalten

Mein Debugging ergab einige interessante Informationen. Wenn ich zuerst einen Wert in der Dropdown-Liste auswähle. Ich habe bemerkt, dass die Datenindrucke dann den SaveViewState von (was ich überholt habe, um mehrere Probleme auf einmal zu lösen), dann der OnSelectedValue Change Fires, der den richtigen Wert darin hat, aber der Save Viewstate bereits bestanden hat. dann tritt das Databind-Ereignis ein zweites Mal auf, und der ursprüngliche Wert ist wegen der Wiederherstellung des Steuerelements verloren.

Also meine Frage hier ist: Gibt es eine Möglichkeit, das Ereignis zu erhöhen, ohne dass das AutoPostBack auf True gesetzt ist?

ODER

Gibt es eine Möglichkeit, wenn Speichern und Laden von Ansichtszustand Feuer zu diktieren?

OR

ist es eine Möglichkeit, die OnSelectedValueChanged Veranstaltung zu zwingen, schneller zu schießen?

Oder fehlt mir etwas? Hier

ist der Code für die Erstellung der Vorlage:

public class GTemplate : Control, ITemplate 
{ 
    protected Control InternalControl; 
    private TemplateType tempType; 
    internal string InnerControlDataSource; 
    internal string DataTextField; 
    internal string DataValueField; 
    internal string InnerControlName; 
    internal string HeaderText; 
    internal string ItemsDataField; 
    public EventHandler EventItem; 
    ControlType innerControl; 



    public GTemplate(TemplateType tt,WSControlItem Item,EventHandler EventItem) 
    { 
     innerControl = (ControlType)Convert.ToInt16(Item.GetAttributeValueByID("InnerControlType")); 
     InnerControlName = Item.GetAttributeValueByID("InnerControlName"); 
     innerBlocking = PageControl; 

     this.EventItem = EventItem; 
     InnerControlDataSource = Item.DataSourceName; 

     DataTextField = Item.GetAttributeValueByID("DataTextField"); 
     DataValueField = Item.GetAttributeValueByID("DataValueField"); 
     ItemsDataField = Item.GetAttributeValueByID("datafield"); 
     HeaderText = Item.Text; 
     EventItem += EventItem; 
     tempType = tt; 


    } 


    public void InstantiateIn(Control container) 
    { 
      switch (tempType) 
      { 

       case TemplateType.Header: 

        switch (innerControl) 
        { 
         case ControlType.DropDownList: 
          GLabel glbl = new GLabel(); 
          glbl.Text = HeaderText; 
          container.Controls.Add(glbl); 
          GDropDownList ddl = new GDropDownList(); 
          ddl.ID = InnerControlName; 
          ddl.isFilter = true; 
          ddl.DataSourceID = InnerControlDataSource; 
          ddl.DataTextField = DataTextField; 
          ddl.DataValueField = DataValueField; 
          ddl.AutoPostBack = true; 

          ddl.SelectedIndexChanged += new EventHandler(EventItem); 
          container.Controls.Add(ddl); 

          break; 

        } 
        break; 
       case TemplateType.EditItem: 
        GLabel lbl = new GLabel(); 
        lbl.ID = "Label_" + InnerControlName; 
        lbl.DataBinding += new EventHandler(tb1_DataBinding); 
        lbl.Text = "'<%# Eval(" + ItemsDataField + ") %>'"; 
        container.Controls.Add(lbl); 
        break; 
      } 

    } 

    protected void tb1_DataBinding(object sender, EventArgs e) 

    { 

     GLabel txtdata = (GLabel)sender; 

     GridViewRow container = (GridViewRow)txtdata.NamingContainer; 

     object dataValue = DataBinder.Eval(container.DataItem, ItemsDataField); 

     if (dataValue != DBNull.Value) 

     { 

      txtdata.Text = dataValue.ToString(); 

     } 
    } 
} 

Wie Sie wahrscheinlich sagen, kann ich mehrere Lösungen ausprobiert haben und verbrachte ein paar Tage versucht, dies herauszufinden. Eine Sache, die ich bemerkte, ist, wenn ich das Ereignis entferne, das der Wert zu und von meinem Save und Ansichtszustandsüberschreibungen ohne Problem überträgt.

Hier ist, wo sie mit dem Netz hinzugefügt:

    GTemplateField gtf = new GTemplateField(Item, Control_LoadBehavior); 
        GGridView ggv3 = (GGridView)Container; 


        gtf.HeaderText = Item.Text; 
        gtf.HeaderTemplate = new GTemplate(TemplateType.Header, Item, Control_LoadBehavior); 

        gtf.ItemTemplate = new GTemplate(TemplateType.EditItem, Item, Control_LoadBehavior); 


        ggv3.Columns.Add(gtf); 

Und last but not least die subclassed (ich hatte auf gemeinsame Eigenschaften zwischen meinen Kontrollen zu halten, so konnte ich den Ansichtszustand außer Kraft setzen) Dropdownlist:

/// <summary> 
/// A custom DropDownList class that extends the functionality of its base class and includes additional properties. 
/// </summary> 
public class GDropDownList: DropDownList 
{ 
    public bool isFilter { get; set; } 

    /// <summary> 
    /// The default constructor for a GDropDownList object. 
    /// </summary> 
    public GDropDownList() 
     : base() 
    { 

    } 

    internal EventHandler InnerEvent; 

    /// <summary> 
    /// Returns the text property of the control. 
    /// </summary> 
    public string ReturnValue 
    { 
     get { return SelectedValue; } 
    } 

    /// <summary> 
    /// Currently, this variable is not being used. 
    /// </summary> 
    public string ReturnSetting; 

    /// <summary> 
    /// Returns the text property of the control. To set the value, see SetViewStateData. 
    /// </summary> 
    public string GetViewStateData 
    { 
     get { return SelectedValue; } 

    } 

    /// <summary> 
    /// Sets the text property of the control. To get the value, see GetViewStateData. 
    /// </summary> 
    public string SetViewStateData 
    { 
     set { SelectedValue = value; } 
    } 

    /// <summary> 
    /// Currently, this property is not being used. 
    /// </summary> 
    public string GetComparitiveValue 
    { 
     get { return ""; } 
    } 

    protected override void OnSelectedIndexChanged(EventArgs e) 
    { 
     string i = SelectedValue;//i need to store the value if its not blank here, Where the fuck do I store it? 
     base.OnSelectedIndexChanged(e); 
    } 

    public override void DataBind() 
    { 

      base.DataBind(); 

     if (isFilter) 
      Items.Insert(0, new ListItem("Select Filter", "")); 


    } 

} 

}

+0

haben Sie einen 'Page_Load' Event-Handler .. wenn ja, suchen Sie nach 'If (IsPostBack) {}' .. klingt wie ein PostBack-Problem nur aus dem Lesen Ihres Titels .. – MethodMan

+0

Ich ging dieses Problem früh an. Alle Steuerelemente werden in einem! Ispostback-Block erstellt. Ich denke, es ist ein Timing-Problem. Die Datenbank scheint zu brennen, dann saveviewstate, dann der ausgewählte Indexwechsel (mit dem richtigen Wert), dann der Lade-View-Status und eine andere Datenbank. –

+0

es ist kein Timing-Problem, es ist Verständnis der 'Seite Life Cycle' sowie was Ereignisse ausgelöst werden und immer ausgelöst in Bezug auf, ob eine Eigenschaft die' Ursachen PostBack'-Set hat .. Sie sollten ein 'If (! IsPostBack) { } else {} 'und auch eine Möglichkeit, erneut zu binden, bevor die Seite gerendert wird .. check in' Pre_Render' Ereignisse, die Sie auch selbst erstellen können, aber Sie müssen wissen und verstehen wann und wo Sie es verwenden können gut wie es nennen. – MethodMan

Antwort

0

Also nach einigen Recherchen und ein paar mehr Versuch und Irrtum entdeckte ich die Kontrolle zerstört wurde, als der OnSelectedValueChange Tanne wurde ed und das SQL-Dataset repopuliert die Datenquelle. Also habe ich einen Wrapper um den Session-Status gelegt, wie in diesem Post vorgeschlagen [link] 'Session' does not exist in the current context und alles funktioniert.

Hier ist der Code I angepasst:

public class MySession 
{ 
    // private constructor 
    private MySession() 
    { 
     Filters = new List<PageValueItem>(); 
    } 

    // Gets the current session. 
    public static MySession Current 
    { 
     get 
     { 
      MySession session = 
       (MySession)HttpContext.Current.Session["__MySession__"]; 
      if (session == null) 
      { 
       session = new MySession(); 
       HttpContext.Current.Session["__MySession__"] = session; 
      } 
      return session; 
     } 

    } 

    public static void SaveFilterValue(string ID, string value) 
    { 
     MySession session = 
       (MySession)HttpContext.Current.Session["__MySession__"]; 
     if (session == null) 
     { 
      session = new MySession(); 
      session.Filters.Add(new PageValueItem(ID, value)); 
      HttpContext.Current.Session["__MySession__"] = session; 
     } 
     else 
     { 
      session.Filters.Add(new PageValueItem(ID, value)); 
      HttpContext.Current.Session["__MySession__"] = session; 
     } 
    } 

    public static string GetFilterValue(string ID) 
    { 
     string retVal = null; 

     MySession session = 
       (MySession)HttpContext.Current.Session["__MySession__"]; 
     if (session != null) 
     { 
      foreach(PageValueItem pvi in session.Filters) 
      { 
       if(pvi.ID == ID) 
       { 
        retVal = pvi.Value; 

       } 
      } 

     } 

     return retVal; 

    } 

    private List<PageValueItem> Filters; 
} 

PageValueItem ist nur ein Objekt, das die ID des Dropdownlist und den Wert speichert.