2014-03-24 220 views
1

請原諒我對此問題缺乏培訓/理解。嵌套類無法訪問「父」變量

我有一個複雜的asp.net/c#包,這是一個高度自定義的電子商務商店。我會盡量簡化我的情況,以便於理解。

我有一個自定義的控制,並在控制的定義是這樣的:

public partial class ConLib_Custom_ProductDialog : System.Web.UI.UserControl 

和類中是這樣的:

private class QtyBoxTemplate : System.Web.UI.ITemplate 

和類中,我解決的價值bool _EventSelected與:

if (_EventSelected) 

它在外部類中定義爲:

public static bool _EventSelected; 

我不想靜態的,因爲它可能會導致網站用戶之間的「衝突」,因爲靜態變量是全局中的應用。之前我們遇到過這個問題,我可以先關掉靜態關鍵字,然後才能正常工作。

在這種情況下,如果我刪除靜態我得到一個錯誤,我有點明白了:

通過嵌套類型ConLib_Custom_ProductDialog.QtyBoxTemplate無法訪問外型ConLib_Custom_ProductDialog的非靜態成員

看起來QtyBoxTemplate是嵌套的,它不能訪問父類中的bool變量。

我發現了另一個類似的問題here,說的多,有三種解決方案:

1. Make the (method) variable static. 
2. Use inheritance instead of nested classes. 
3. Create an instance of the outer class. 

首先是一個問題,因爲它是一個變量,而不是如在原崗位的方法,但它是如何我一直工作到目前爲止,並沒有意識到這一點。

至於第二,我不認爲繼承是一種選擇,因爲QtyBoxTemplate已經繼承了System ITemplate。

最後,爲了訪問一個變量而創建一個外部類的實例似乎很奇怪,而且我的經驗不足,我甚至不知道如何工作 - 我什麼時候創建實例,是否必須傳遞它等等。由於它是一個自定義控件,我甚至不知道是否可以這樣做,因爲它不是已經通過它所在的父頁面實例化了嗎?

再次,道歉提出一個問題可能是基本的你,但這是我只是沒有得到的一部分。我意識到代碼有點複雜,希望我能夠充分理解它的本質。非常感謝幫助。

更新:試圖添加更多信息。我有一個數據網格,每行是產品。在網格行內,我有一個從1到10的數量的下拉列表。但是,如果他們已經選擇了座位並且已經選擇了日期/時間,他們就不能更改數量或它會弄亂保留系統,所以我檢查_EventSelected以禁用數量DDL(如果是這種情況)。

我們使用DDL作爲數量,因爲它是一個移動商店,它們比原始商店中的向上/向下箭頭更容易。這一切都非常複雜 - 一個商業商店包和兩個不同的承包商已經將它與其他預訂系統聯繫起來,我必須理解這一切並使其工作。希望我更瞭解.NET/C#!感謝通過這個解釋試圖幫助。

這裏是我的QtyBoxTemplate類:

private class QtyBoxTemplate : System.Web.UI.ITemplate 
    {    
     private DataControlRowType templateType; 
     private string columnName; 

     public QtyBoxTemplate(DataControlRowType type, string colname) 
     { 
      templateType = type; 
      columnName = colname; 
     } 

     public void InstantiateIn(System.Web.UI.Control container) 
     { 
      Literal lc = new Literal(); 

      switch (templateType) 
      { 
       case DataControlRowType.Header: 
        // build the header for this column 
        //lc.Text = "<b>" + BreakCamelCase(columnName) + "</b>"; 
        lc.Text = "<b>" + columnName + "</b>"; 
        container.Controls.Add(lc); 
        break; 
       case DataControlRowType.DataRow: 
        //--plugables: Now we need a drop down list instead of a quantity box 
        DropDownList ddList = new DropDownList(); 
        ddList.Items.Add(new ListItem("0", "0")); 
        ddList.Items.Add(new ListItem("1", "1")); 
        ddList.Items.Add(new ListItem("2", "2")); 
        ddList.Items.Add(new ListItem("3", "3")); 
        ddList.Items.Add(new ListItem("4", "4")); 
        ddList.Items.Add(new ListItem("5", "5")); 
        ddList.Items.Add(new ListItem("6", "6")); 
        ddList.Items.Add(new ListItem("7", "7")); 
        ddList.Items.Add(new ListItem("8", "8")); 
        ddList.Items.Add(new ListItem("9", "9")); 
        ddList.Items.Add(new ListItem("10", "10")); 
        ddList.Items.Add(new ListItem("20", "20")); 
        ddList.Items.Add(new ListItem("40", "40")); 
        ddList.ID = "Quantity"; 
        ddList.Font.Size = FontUnit.Parse("18px"); 
        if (_EventSelected) 
         ddList.Enabled = false; 
        container.Controls.Add(ddList); 
        break; 
       default: 
        break; 
      } 
     } 
    } 

而且它生活在類中有許多方法,類等等......太多在這裏(2500+線)職位,但它開始像:

public partial class ConLib_Custom_BuyTourProductDialogGalaxy : System.Web.UI.UserControl 
{ 
    #region class variables 

    int _ProductId = 0; 
    Product _Product = null; 
    List<int> _SelectedKitProducts = null; 
    ProductVariantManager _VariantManager; 
    PersistentCollection<ProductVariant> _AvailableVariants; 
    DataTable _DataTable; 
    ProductOptionCollection _ProdOptions; 

    private bool _ShowAvailableSeats = true; 
    public DateTime _SelectedDate; 
    public int _EventTypeId; 
    public bool _CollectRosterData; 
    public Envelope _Inventory; 
    private string _DTFormat = "yyyy-MM-dd HH:mm:ss"; 

    public bool _EventSelected; 
+4

你不需要創建一個* new *實例 - 你大概已經*有*一些實例。目前還不清楚究竟發生了什麼或者你想要實現什麼,但是我可能會從刪除嵌套開始 - 這可能會導致更多的混亂,而不是價值。 –

+0

你可以創建它自己的屬性_EventSelected用於嵌套類並將其設置在外部_EventSelected屬性的setter中? – lavrik

+0

是的,這是一個涉及到的系統,我在.NET上是一個新手,我甚至很難解釋。我會盡力將其分解出來,看看我能得到什麼。謝謝。 – Deverill

回答

1

由於QtyBoxTemplate是私密的,因此只能在ConLib_Custom_ProductDialog類中創建。
我建議您將ConLib_Custom_ProductDialog作爲參數添加到QtyBoxTemplate構造函數中,並將其設置爲局部變量。然後您可以使用該參考訪問_EventSelected

public partial class ConLib_Custom_ProductDialog : System.Web.UI.UserControl 
{ 
    public bool _EventSelected; 

    public void SomeFunctionThatCreatesQtyBoxTemplate() 
    { 
     var q = new QtyBoxTemplate(this); //Include reference to itself 
     q.SetEventSelected(); 
    } 

    private class QtyBoxTemplate : System.Web.UI.ITemplate 
    { 
     private ConLib_Custom_ProductDialog _ccp; 

     public QtyBoxTemplate(ConLib_Custom_ProductDialog ccp) 
     { 
      _ccp = ccp; 
     } 

     public void SetEventSelected() 
     { 
      _ccp._EventSelected = true; //Access to "parent" EventSelected 
     } 
    } 
} 
+0

我可以看到現在開展這項工作的路徑。謝謝!這只是一個思維問題,而不是我習慣的線性C編程。 – Deverill

1

您無法從嵌套類中訪問類的實例成員。它沒有任何意義,因爲嵌套類沒有引用外部類的特定實例,除非您傳遞它。在構建嵌套類的實例時,您可以傳遞外部類的實例,但沒有更多代碼,我很難知道此解決方案是否適合您。

說一種不同的方式:儘可能地嘗試並依賴於dependency inversion principle。避免在你正在工作的課程之外引用某些東西。