Dynamiczne dodawanie pozycji do comboBox

0

W moim programie mam dwa comboBox'y. CbxModel jest zależny od CbxMarka.

  1. Po uruchomieniu programu i wybraniu wartości w CbxMarka mój CbxModel jest pusty. Dlaczego?
  2. Jak mam wyczyścić CbxMarka? Po każdym rozwinięciu listy dodają się ponownie jego wartości.
private void CbxMarka_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            CbxMarka.Items.Add("Volksvagen");
            CbxMarka.Items.Add("OPEL");
            CbxMarka.Items.Add("Ford");
            CbxMarka.Items.Add("Audi");
        }

private void CbxModel_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            if (CbxMarka.SelectedItem == "Volksvagen")
            {
                CbxModel.Items.Add("Passat");
                CbxModel.Items.Add("Bora");
                CbxModel.Items.Add("Jetta");
            }
            else if (CbxMarka.SelectedItem == "OPEL")
            {
                CbxModel.Items.Add("Astra");
                CbxModel.Items.Add("Corsa");
                CbxModel.Items.Add("Tigra");
            }
            else if (CbxMarka.SelectedItem == "Ford")
            {
                CbxModel.Items.Add("Mondeo");
                CbxModel.Items.Add("Focus");
                CbxModel.Items.Add("Fiesta");
            }
            else if (CbxMarka.SelectedItem == "Audi")
            {
                CbxModel.Items.Add("A4");
                CbxModel.Items.Add("A5");
                CbxModel.Items.Add("A6");
            }
        }
2

Po uruchomieniu programu i wybraniu wartości w CbxMarka mój CbxModel jest pusty. Dlaczego?

A czy na pewno masz dobrze podpięte zdarzenie, które ma się wykonać po wybraniu elementu z pierwszego comboBox'a?
Testowo możesz dać na początku CbxModel_SelectedIndexChanged jakiegoś MessageBox i zobacz, czy coś się w ogóle pokaże.

Jak mam wyczyścić CbxMarka? Po każdym rozwinięciu listy dodają się ponownie jego wartości.

Skoro dodajesz przez CbxModel.Items.Add, to może analogicznie CbxModel.Items.Clear? ;)

0

MessageBox też się nie wyświetla. Event'y dla CbxModel mam ustawione tak samo jak dla innych.

Próbowałam z CbxModel.Items.Clear na początku CbxMarka ale to powodowało, że po wybraniu z niego wartości i przejściu do kolejnego MeesageBox mój CbxMarka już był pusty.

2

Skoro komunikat się nie wyświetla, to znaczy, że z jakiegoś powodu zdarzenie nie zostało poprawnie podpięte, przez co nie wywołuje się jego procedura obsługi. Musisz pokombinować, dlaczego tak się dzieje ;)

Próbowałam z CbxModel.Items.Clear na początku CbxMarka

No ale moim zdaniem to czyszczenie powinno być nie w obsłudze Marki, ale Modelu. A konkretnie w if, na początku każdego bloku, który wypisuje modele. Nie czyścisz tego, dopóki nie dojdzie do wyboru i nie pojawi się konieczność wypisania nowych wartości. Wtedy przed pierwszym CbxModel.Items.Add wstawiasz polecenie czyszczenia.

0
cerrato napisał(a):

Skoro komunikat się nie wyświetla, to znaczy, że z jakiegoś powodu zdarzenie nie zostało poprawnie podpięte, przez co nie wywołuje się jego procedura obsługi. Musisz pokombinować, dlaczego tak się dzieje ;)

Próbowałam z CbxModel.Items.Clear na początku CbxMarka

No ale moim zdaniem to czyszczenie powinno być nie w obsłudze Marki, ale Modelu. A konkretnie w if, na początku każdego bloku, który wypisuje modele. Nie czyścisz tego, dopóki nie dojdzie do wyboru i nie pojawi się konieczność wypisania nowych wartości. Wtedy przed pierwszym CbxModel.Items.Add wstawiasz polecenie czyszczenia.

Z comboBox'em jakoś się udało. Gorzej z czyszczeniem, bo po dodaniu do każdego if na początku CbxMarka.Items.Clear i próbie uruchomienia programu pojawia się komunikat odnośnie string marka = CbxMarka.SelectedItem.ToString();, że "Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu" - dodam, że bez czyszczenia wszystko działa.

0

CbxMarka.SelectedItem jest null, bo żaden element nie jest zaznaczony.

0

zdarzenia są źle podpięte, nie ma sensu jak Marka się zmieniła dopiero ustawiać listę wyboru.
Prawidłowo wykonany ten 'wzorzec' polega na tym, że

Onchange_Poprzednik (){
NastepneCombo.Clear()
NazstępneCOmbo.Add("jeden")
NazstępneCOmbo.Add("dwa")
NazstępneCOmbo.Add("trzy")
}

Podpięcie zdarzeń "na sobie" na "wypełnienie swojej listy" mogło by mieć sens na jakimś bardzo wczesnym zdarzeniu "GotFocus", czy co tam masz.

0

Ok, to już zrobiłam. Mam jeszcze jedno pytanie odnośnie:

public int Ceny(string marka, string model, int silnik)
        {
            marka = CbxMarka.SelectedItem.ToString();
            model = CbxModel.SelectedItem.ToString();
            silnik = Convert.ToInt32(CbxSilnik.SelectedItem);
            int cena;

            if (marka == "Volkswagen")
            {
                if (model == "Passat")
                {
                    if (silnik == 100)
                    {
                        cena = 5000;
                    }
                    else if (silnik == 180)
                    {
                        cena = 10000;
                    }
                    else if (silnik == 250)
                    {
                        cena = 15000;
                    }
                }
                else if (model == "Bora")
                {
                    if (silnik == 100)
                    {
                        cena = 4000;
                    }
                    else if (silnik == 180)
                    {
                        cena = 8000;
                    }
                    else if (silnik == 250)
                    {
                        cena = 12000;
                    }
                }
			}
			return cena;
		}

Mam komunikat: Use of unassigned local variable 'cena'. Dlaczego?

2

Zmienna cena jest zmienną lokalną, które nie są automatycznie inicjalizowane, czyli mówiąc po ludzku - nie zostaje im przypisana w momencie tworzenia żadna wartość, nie są zerowane itp. Dlatego, przed jej użyciem, powinna zostać najpierw przypisana jakaś wartość.

W Twoim przykładzie tak się dzieje - we wszystkich przypadkach cena jest po lewej stronie, czyli właśnie zostaje jej przypisana wartość. To jest OK, błędem by było napisanie czegoś w stylu wartosc = cena * ilosc, jeśli cena nie została wcześniej przypisana, ale takiego zapisu nie masz.

No to o co chodzi w takim razie? Na samym końcu masz return cena. I powiedz mi proszę, jeśli marka nie będzie równa "Volkswagen", a model nie będzie miał wartości "Bora" ani "Passat", to co zostanie zwrócone przez to return cena?

Jeżeli kojarzysz angielski i chcesz się czegoś więcej dowiedzieć/poczytać, to rzuć okiem na https://stackoverflow.com/questions/9233000/why-compile-error-use-of-unassigned-local-variable

0
cerrato napisał(a):

Zmienna cena jest zmienną lokalną, które nie są automatycznie inicjalizowane, czyli mówiąc po ludzku - nie zostaje im przypisana w momencie tworzenia żadna wartość, nie są zerowane itp. Dlatego, przed jej użyciem, powinna zostać najpierw przypisana jakaś wartość.

Świetnie Pan tłumaczy! :) int cena=0 rozwiązuje problem. Byłam przekonana, że tu wartością domyślną jest 0. Bardzo dziękuję za pomoc :)

0

Kolejny problem. Wszystkie moje combobox'y znajdują się znajduą się w tej samej klasie jak ten poniżej:

namespace WindowsFormsApp2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public void CbxMarka_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            CbxMarka.Items.Add("Volksvagen");
            CbxMarka.Items.Add("OPEL");
            CbxMarka.Items.Add("Ford");
            CbxMarka.Items.Add("Audi");
        }
    }
}

Jak mam się do niego odwołać (a konkretnie do wybranej wartości: CbxMarka.SelectedItem) w innej klasie? np, chciałabym przypisać wybraną wartość do zmiennej: string marka = CbxMarka.SelectedItem.ToString();

0

Możesz np. przekazać combox podczas tworzenia tej drugiej klasy albo od razu wybraną wartość.
PS WinForms jest konieczny? Polecam WPF i Bindingi

0

W jaki sposob mam to zrobic? Jak przekazac combox lub wybrana wartosc?

0

W klasie do której chcesz przekazać wartość modyfikujesz konstruktor.

public OtherClass(string comboBoxValue)
{
    
}

Później tworząć obiekt tej klasy przekazujesz wartość odczytaną z ComboBoxa.

var otherClass = new OtherClass(comboBoxValue);

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