Wątek przeniesiony 2015-09-12 22:31 z C# i .NET przez somekind.

Jak pokonać error w działaniu listboxa przy wyborze drugiej opcji?

0

Error:
"Object reference not set to an instance of an object."
Error pojawia się podczas działania programu wtedy, gdy wybieram nie pierwszą opcję case=0, tylko drugą=1. Gdy najpierw wybieram opcję zero, to wszystko gra. Error jest wtedy, gdy wybór zaczynam od case 1. "granice" to po prostu zakładka w tabcontrol.

Już doczytałem w stackoverflow, że tu chodzi o jakąś wartość null, ale dlaczego w takim razie wszystko działa, gdy wybieram opcję 0 a potem 1.
Sory za porąbane nazwy zmiennych. Np txt_a_kwadratowa to nazwa txtboxa, etykieta to label. Po prostu jak się ma tyle tego, to pomysłów brakuje jak to wszystko sensownie po nazywać.

case 0:
inne kontrolki <-bardzo ich dużo, więc ich nie wklejam,bo by 10 stron post zajął
break;
case 1:
                    
                    
                        granice.Controls.Remove(txt_a_kwadratowa);
                        granice.Controls.Remove(etykieta_a_kw);
                        
                        

                        this.txt_a_kwadratowa = new TextBox();
                        this.txt_a_kwadratowa.Name = "txt_a_kwadratowa";
                        this.txt_a_kwadratowa.Visible = true;
                        this.txt_a_kwadratowa.Location = new Point(60, 100);
                        this.txt_a_kwadratowa.Size = new Size(30, 30);
                        this.txt_a_kwadratowa.ReadOnly = true;
                        this.txt_a_kwadratowa.BorderStyle = BorderStyle.FixedSingle;
                        //etykieta a dla kwadratorej
                        this.etykieta_a_kw = new Label();
                        this.etykieta_a_kw.Name = "etykieta_a_kw";
                        this.etykieta_a_kw.Size = new Size(15, 15);
                        this.etykieta_a_kw.Location = new Point(70, 85);
                        this.etykieta_a_kw.Visible = true;
                        this.etykieta_a_kw.Text = "A";

                        __this.txtb_fl_a.Visible = false;__                          //**tę linię wskazuje error**
                        granice.Controls.Remove(txtb_fl_a);
                        granice.Controls.Add(txt_a_kwadratowa);
                        granice.Controls.Add(etykieta_a_kw);
                       

                        granice.Controls.Remove(etykieta_a);
                        granice.Controls.Remove(txtb_fl_a);
                        break;
                    
 
0

widocznie jest nullem, ustaw pulapke i debuguj. czemu nie utworzysz sobie gui np na panelach, controlkach, tylko tak dodajesz? latwiej by to garnac bylo.

0
.Al napisał(a):

widocznie jest nullem, ustaw pulapke i debuguj. czemu nie utworzysz sobie gui np na panelach, controlkach, tylko tak dodajesz? latwiej by to garnac bylo.

Bo głupi jestem. Być może dlatego. Co masz na myśli przez Gui?? Ech...ignorant ze mnie.

1

Właśnie jak ukryjesz panel, to znika z całą zawartością. Dlatego nie warto się rozdrabniać jeżeli już robisz tak jak robisz (coś jak instalator). Ewentualnie możesz użyć tab'ów, albo zrobić sobie własne controlki (coś jak panel, tylko każdą 'stronę' masz w osobnym 'itemie' i łatwiej nad kodem zapanować).

0

.Al, dzięki, to mi wiele ułatwi. Zastanawiam się jednak jak rozwiązać problem, który powstaje gdy np. kliknę dwa lub więcej racy na ten sam item w listboxie. Bo chodzi o to, że wtedy np wartość case 1 zapisuje się w pamięci więcej niż jeden raz. I gdy wybieram potem case 0, to case 1 nie znika.

Nie wiem, może z tym gui będzie rzeczywiście prościej.

0

Najprościej to dodać jakąś flagę (boolean) która będzie mówiła o tym czy to pierwsze wywołanie (wtedy utworzy komponenty) czy kolejne.

0
hipekk napisał(a):

Najprościej to dodać jakąś flagę (boolean) która będzie mówiła o tym czy to pierwsze wywołanie (wtedy utworzy komponenty) czy kolejne.

Znalazłem coś takiego na stacku. O coś podobnego ci chodzi?

public List<string> previouslyClickedOptions {
    get {
       if (ViewState["prevClicked"] == null)
           ViewState["prevClicked"] = new List<string>();
       return (List<string>)ViewState["prevClicked"];
    }
}
string currentlySelected = myLB.SelectedValue;
bool clickedBefore = previouslyClickedOptions.Contains(currentlySelected);
if (!clickedBefore)
   previouslyClickedOptions.Add(currentlySelected);
 
0

ja bym zrobił coś takiego, nie wiem czy Ci dokładnie o to chodzi:

class Test
{
	Control1 c1 = new Control1();
	Control2 c2 = new Control2();
	Control3 c3 = new Control3();
	Control4 c4 = new Control4(); //twoje controlki
	
	UserControl CurrentControl = c1; //aktualna
	
	public void ListBoxIndexChanged() //zmiana
	{	
		this.panel1.Remove(this.CurrentControl); //usuwasz aktualna
		
		switch (NieWiemJakWybierasz)
		{
			case 1:
				this.panel1.Add(this.c1); //dodajesz nowa
				this.CurrentControl = this.c1;
				break;
			case 2:
				this.panel1.Add(this.c2);
				this.CurrentControl = this.c2;
				break;
				
			//itd..
		}
	}
}

Pisałem w notepadzie, to tylko taki 'pseudokod'. Myślę że na jakiś nie bardzo skomplikowany program będzie ok. Jak nie chcesz 2 razy tej samej dodawać, to możesz przed remove dodac jakis warunek, np

if (aktualna == wybrana)
    return;

/w konstruktorze kontrolki daj sobie dock na Fill

0

Wiesz może jak to ominąć? W kodzie dużymi literami opisałem info od kompilatora

.Al napisał(a):

ja bym zrobił coś takiego, nie wiem czy Ci dokładnie o to chodzi:

class Test
{
	Control1 c1 = new Control1();
	Control2 c2 = new Control2();
	Control3 c3 = new Control3();
	Control4 c4 = new Control4(); //twoje controlki
	
	UserControl CurrentControl = c1; //aktualna <-COMPILATOR PODRESLA C1 I INFORMUJE, ZE NIE MOZE PRZEKONWERTOWAC Z 
 USERCONTROL NA TEXBOX
	
	public void ListBoxIndexChanged() //zmiana
	{	
		this.panel1.Remove(this.CurrentControl); //usuwasz aktualna
		
		switch (NieWiemJakWybierasz)
		{
			case 1:
				this.panel1.Add(this.c1); //dodajesz nowa
				this.CurrentControl = this.c1;
				break;
			case 2:
				this.panel1.Add(this.c2);
				this.CurrentControl = this.c2;
				break;
				
			//itd..
		}
	}
}

Pisałem w notepadzie, to tylko taki 'pseudokod'. Myślę że na jakiś nie bardzo skomplikowany program będzie ok. Jak nie chcesz 2 razy tej samej dodawać, to możesz przed remove dodac jakis warunek, np

if (aktualna == wybrana)
    return;

/w konstruktorze kontrolki daj sobie dock na Fill

1

mi bardziej chodziło o coś takiego: prawym na projekt, new item, usercontrol

user image

Nie żebyś tam sobie pisał controlki typu textbox, checkbox, tylko te stworzone przez Ciebie UserControl (a w nich tak jakby 'czesci programu').

A jak juz tam chcesz TextBoxa przypisac, to nie UserControl tylko samo Control.

Może nie umiem tego lepiej opisać na szybko, ale jak już zacząłem temat to odpisuję ;)

0

Z tym panelem to jakieś dziwne rzeczy są. Zrobiłem tak:

 
Panel() p = new Panel();
// size,location, name itd panelu
//dalej:
granice.Control.Add(p); //granice to zaklada tabcontrol
p.controls.add(ronze rzeczy);
...
p.controls....

Gdy dokonuję wyboru to panel pojawia się i znika, ale już controlek na tym panelu widać. Jakieś pomysły?

1 użytkowników online, w tym zalogowanych: 0, gości: 1