clasa imbricate nu poate avea acces la variabila „părinte“

voturi
1

Vă rugăm să scuzați lipsa mea de formare / înțelegere în această problemă.

Am un pachet complex # asp.net / c, care este un magazin de comert electronic extrem de personalizate. Voi încerca să simplifice situația mea pentru ușurința înțelegerii.

Am un control personalizat și în acest control este definit astfel:

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

și în această clasă este aceasta:

private class QtyBoxTemplate : System.Web.UI.ITemplate

și în acea clasă mă adresez valoarea unui bool _EventSelected cu:

  if (_EventSelected)

care este definită în clasa exterioară ca:

public static bool _EventSelected;

Nu vreau static, deoarece aceasta poate provoca „ciocniri“ între utilizatorii site-ului, deoarece variabilele statice sunt globale la Aplicație. Am avut această problemă înainte și am putea lua chiar lângă cuvântul cheie static și a mers.

În acest caz, dacă am elimina static I a lua o eroare pe care am înțeles cam:

Nu se poate accesa un membru non-static de tip exterior prin intermediul ConLib_Custom_ProductDialog tip ConLib_Custom_ProductDialog.QtyBoxTemplate imbricată

Se pare că din moment ce QtyBoxTemplate este imbricat nu poate accesa variabila bool în clasa părinte.

Am găsit o altă întrebare similară aici , care spune că la fel de mult și că există trei soluții:

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

Prima este o problemă, deoarece este o variabilă în locul unei metode ca și în original post, dar este modul în care am muncit până acum și nu-l dau seama.

În ceea ce privește al doilea, nu cred că moștenirea este o opțiune, deoarece QtyBoxTemplate este deja moștenind ITemplate System.

În cele din urmă se pare ciudat pentru a crea o instanță a clasei exterioare doar pentru a avea acces la o variabilă și în lipsa de experienta mea eu nici măcar nu știu cum că ar putea lucra - Când pot crea instanta, nu trebuie să-l treacă în jurul valorii, etc. Deoarece este un control particularizat eu nici măcar nu știu dacă acest lucru se poate face, deoarece nu este ea deja instanțiat de pagina părinte pe care trăiește?

Din nou, scuze pentru a pune o întrebare, care este, probabil, de bază pentru cele mai multe dintre voi, dar aceasta este o parte pur și simplu nu înțeleg. Îmi dau seama că codul este oarecum complexă și sper am capturat esența suficient de bine pentru a face sens. Ajutor este foarte apreciat.

Actualizați: Încercarea de a adăuga mai multe informații. Am o grilă de date în cazul în care fiecare rând este un produs. În interiorul rândul respectiv grila am o listă derulantă pentru cantitatea pe care doresc să cumpere, de la 1 la 10. Cu toate acestea, în cazul în care au ales locuri pe un tur și au selectat deja o dată / timp pentru a merge nu pot schimba cantitatea sau se va strica sistemul de rezervare , așa că am verifica _EventSelected pentru a dezactiva cantitatea DDL , dacă este cazul.

Noi folosim o DDL pentru cantitate, deoarece este un magazin de telefonie mobilă și acestea sunt mai ușor decât săgețile sus / jos în magazin original. Acest lucru este foarte complex - un pachet magazin comercial și 2 contractori diferite au lucrat la ea să-l lega într-un alt sistem de rezervare și trebuie să-l înțeleagă toți și face să funcționeze. Aș vrea să știu mai multe .NET / C #! Vă mulțumim pentru trudging prin această explicație pentru a încerca să ajute.

Iată clasa mea 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;
            }
        }
    }

Și trăiește în interiorul unei clase cu zeci de metode, clase, etc ... prea mult pentru a posta aici (2500+ linii), dar începe așa:

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;
Întrebat 24/03/2014 la 14:01
sursa de către utilizator
În alte limbi...                            


2 răspunsuri

voturi
1

Nu puteți accesa membri instanta a unei clase din cadrul unei clase imbricate. Nu are nici un sens, deoarece clasa imbricate nu are o referință la o anumită instanță a clasei exterioare, dacă nu îl treci unul. Ai putea trece o instanță a clasei exterioare atunci când se construiește instanțe ale clasei imbricate, dar fără a mai mult cod, este dificil pentru mine să știu dacă această soluție ar lucra pentru tine.

A spus un alt mod: încercați și să se bazeze pe principiul inversiune de dependență ori de câte ori se poate. Evitați referirile la lucrurile din afara clasei la care lucrați.

Publicat 24/03/2014 la 14:35
sursa de către utilizator

voturi
1

Deoarece QtyBoxTemplateeste privat poate fi creat doar în interiorul ConLib_Custom_ProductDialogclasei.
Aș sugera să adăugați ConLib_Custom_ProductDialogca parametru la QtyBoxTemplateconstructor și setați - o ca o variabilă locală. Apoi , puteți accesa _EventSelectedutilizând această trimitere.

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 
        }
    }
}
Publicat 24/03/2014 la 14:35
sursa de către utilizator

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more