2016-07-01 12 views
-1

私は少しの状況があります。私はaspに新しい.net winformsで古い帽子。私は現在ASPページを動的に生成しています。最近、フィルターのドロップダウンを列ヘッダーに入れるように求められました。だから私は、テンプレートと列を生成し、名前とドロップダウンのラベルを追加するメソッドを作成しました。大きな問題ではない。もともと私はイベントを得ることができませんでしたので、AutoPostBack = trueに設定してイベントを発生させましたが、値は保持されません。GridViewのDropDownList値が保持されない

私のデバッグでは、いくつか興味深い情報が明らかになりました。最初にドロップダウンリストの値を選択したとき。私はdatabindの火災に気づき、SaveViewStateが行くと(一度に複数の問題を解決するために乗り越えた)、OnSelectedValuechangeが正しい値を持ちますが、Save Viewstateが既に渡されています。 Databindイベントが2回発生し、コントロールの再作成のために元の値が失われます。

私はここで私の質問と思います:AutoPostBack Beingをtrueに設定せずにイベントを発生させる方法はありますか?

OR

時に保存してロードビューステート火を決定する方法はありますか?

OR

早く発射するOnSelectedValueChangedイベントを強制する方法はありますか?

何か不足していますか?あなたはおそらく、私はいくつかのソリューションを試してみましたが、これを理解しようとしている数日費やしてきた言うことができるように

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

     } 
    } 
} 

:ここ

は、テンプレートを作成するためのコードです。私が気付いたことの1つは、値が渡されたイベントを取り除いて保存して、ロード状態のオーバーライドを問題なく表示する場合です。それらがグリッドに追加されているのはここ

は次のとおりです。

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

そして最後にではなく、少なくとも、サブクラス化(私はビューステートをオーバーライドすることができるように、私のコントロール間で共通のプロパティを維持するためにしなければならなかった)の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

あなたは 'Page_Load'イベントハンドラを持っていますか?もしそうなら' If(IsPostBack){} 'はあなたのタイトルを読むことからちょうどポストバックのように聞こえる.. – MethodMan

+0

私はその問題を早い段階で解決しました。 !ispostbackブロック内にすべてのコントロールが作成されています。私はタイミングの問題だと思う。データバインドが発火してからsaveviewstateのように見え、次に選択されたエクスチェンジが起動して(適切な値を持つ)、次にviewstateと別のデータバインドがロードされます。 –

+0

タイミングの問題ではありません。 'Page Life Cycle'を理解しているだけでなく、プロパティに'原因PostBack'が設定されている場合にトリガされ、常にトリガされるイベントがあります。 'if(!isPostBack){ } else {} 'また、ページがレンダリングされる前に再バインドする方法。自分で作成することができる' Pre_Render'イベントをチェックしますが、いつ、どこでそれを使うべきかを理解するだけでなく、よく電話してください。 – MethodMan

答えて

0

だから、いくつかの研究とさらにたくさんの試行錯誤の後、私はOnSelectedValueChangeはモミされたときにコントロールが破壊されていた発見SQLデータセットはデータソースを再投入します。だから私はこの記事[リンク] 'Session' does not exist in the current contextで提案されているように、セッション状態の周りにラッパーを入れて、すべて動作しています。

ここでIは適応コードは次のとおり

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がDropDownListの値のIDを格納するだけの目的です。