Windows Form Pomoc - InvalidCastException

0

Witam, z góry mówię że jestem bardzo początkujący więc proszę o konkretne wyjaśnienie i podanie rozwiązania jeśli to możliwe.

Kiedy klikam po lewej stronie w oknie na jakaś nazwe to pokazuję mi się ten błąd.

Problem jaki mi się pokazuje to: "System.InvalidCastException: „Unable to cast object of type 'System.String' to type 'AdressBook_2.Person"

namespace AdressBook_2
{

    public class Person
    {      
        public string  Name { get; set; }

        public string Gatu { get; set; }

        public string Postnr { get; set; }

        public string Postort { get; set; }

        public string Telefon { get; set; }

        public string Email { get; set; }
     
        

        public Person(string name, string gatu, string postnr, string postort, string telefon, string email)
        {
            Name = name;
            Gatu = gatu;
            Postnr = postnr;
            Postort = postort;
            Telefon = telefon;
            Email = email;
        }

        public Person()
        {

        }
        public bool Register()
        {

            string file = @"C:\temp\AdressBok.txt";

            using (StreamWriter _writer = new StreamWriter(file, true))
            {               
                //Metoden kollar om email är rätt inskriven då registeras 
                if (CheckEmail())
                {                             
                    string row = $"{Name}, {Gatu}, {Postnr}, {Postort}, {Telefon}, {Email}";

                    _writer.WriteLine(row);
                    _writer.Close();
                    return true;                    
                }
                else return false;
            }
        }
        public bool CheckEmail()
        {
            
            if (Email.Contains('@') && Email.Contains('.'))
            {
                return true;
            }
            else
            {
                MessageBox.Show("Brakuje @");
                return false;
            }
        }
    }
}
namespace AdressBook_2
{
    public partial class Form1 : Form
    {   
        public string path = @"C:\temp\AdressBok.txt";
        
        public List<Person> personer = new List<Person>();
        bool start = false;
        public Form1()
        {
            InitializeComponent();           
        }
        private void Avslutaknap_Click(object sender, EventArgs e)
        {
            
            this.Close();
        }

        private void Rensaknap_Click(object sender, EventArgs e)
        {
            
            listBox1.Items.Clear();
            textBox1.Clear();
            textBox2.Clear();
            textBox3.Clear();
            textBox4.Clear();
            textBox5.Clear();
            textBox6.Clear();
        }

        public void Form1_Load(object sender, EventArgs e)
        {   
            
            Person load;
            StreamReader sr = new StreamReader(@"C:\temp\AdressBok.txt");
            string line = "";
            while (!sr.EndOfStream)
            {
                load= new Person();
                line = sr.ReadLine();
                var array = line.Split(',');
                load.Name = array[0];
                load.Gatu = array[1];
                load.Postnr = array[2];
                load.Postort = array[3];
                load.Telefon = array[4];
                load.Email = array[5];
                personer.Add(load);                
            }
            sr.Close();

            var file = @"C:\temp\AdressBok.txt";
            if (!File.Exists(file))
                File.Create(file);
        }

        private void Registeraknap_Click(object sender, EventArgs e)
        {    
            /
            Person person = new Person(textBox1.Text, textBox2.Text, textBox3.Text, textBox4.Text, textBox5.Text,
                textBox6.Text);
            personer.Add(person);

            if (person.Register())
            {
                listBox1.Items.Add(person.Name);
                //Rensar textbox efter man har tryck register kanpen
                textBox1.Clear();
                textBox2.Clear();
                textBox3.Clear();
                textBox4.Clear();
                textBox5.Clear();
                textBox6.Clear();               
            }           
        }
        private void Ladda_uppknap_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
        
            List<string> lines = File.ReadAllLines(path).ToList();
            foreach (string line in lines)
            {
                listBox1.Items.Add(line);
            }            
        }
        private void Sökknap_Click(object sender, EventArgs e)
        {
            
            listBox1.Items.Clear();
            string text = textBox7.Text;
            foreach (Person person in personer)
            {
                if (person.Name.ToLower().Contains(text.ToLower()))
                {
                    listBox1.Items.Add(person.Name);
                    textBox1.Text = person.Name;
                    textBox2.Text = person.Gatu;
                    textBox3.Text = person.Postnr;
                    textBox4.Text = person.Postort;
                    textBox5.Text = person.Telefon;
                    textBox6.Text = person.Email;
                }
            }
        }

        private void Ta_bortknap_Click(object sender, EventArgs e)
        {
            
          

        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

           
                listBox1.SelectedItem.ToString();
                Person person = ((Person)listBox1.SelectedItem);
                textBox1.Text = person.Name;
                textBox2.Text = person.Gatu;
                textBox3.Text = person.Postnr;
                textBox4.Text = person.Postort;
                textBox5.Text = person.Telefon;
                textBox6.Text = person.Email;

        }

Druga sprawa jak zrobić żeby usuwać wcześniej dodany kontakt? oraz jak go edytować?

1

private void Ta_bortknap_Click(object sender, EventArgs e)

Skąd to zerżnąłeś? Autor żyje (żył) gdzieś w ciepłych krajach ?

Zrób mniej, 10, 20, 30 linii, ale własnymi palcami.
I przeczytaj coś

0

Sam to pisałem mieszkam w Szwecji :) ale widze że tutaj niestety nie ma ludzi którzy się znają na programowaniu i nikt nie pomoże :(

chciałem tutaj jeszcze wstawić zdjęcie ale niestety strona nie posiada takiej możliwości :) wszystko poblokowane

screenshot-20220922015516.png

1

Wszystko masz napisane w treści błędu System.InvalidCastException: „Unable to cast object of type 'System.String' to type 'AdressBook_2.Person. Nie można "tak sobie" ze stringa zrobić obiekt Person.

Zakładam, że chodzi o tą linię

 Person person = ((Person)listBox1.SelectedItem);

Po drugie, do takich rzeczy jak .csv korzysta się z CsvHelper. Nie musisz klepać wszystkich splitów ręcznie.

0

Dziękuję za poradę. Uczę się programowania w szkolę od 2 tygodniu nie wszystko potrafię. Plus minus wiem w czym leży problem ale nie wiem jak go rozwiązać.

foreach(Person person in personer)
            {

                if (listBox1.SelectedItem == person.Name.ToString()|| listBox1.SelectedItem == person.Gatu.ToString() || listBox1.SelectedItem == person.Postnr.ToString()||
                    listBox1.SelectedItem == person.Postort.ToString()||  listBox1.SelectedItem == person.Telefon.ToString() || listBox1.SelectedItem == person.Email.ToString())
                {

                    MessageBox.Show(person.Name + " " + person.Gatu + " " + person.Postnr + " " + person.Postort + " " + person.Telefon + " "
                        + person.Email);

                    textBox1.Text = person.Name.ToString();
                    textBox2.Text = person.Gatu.ToString();
                    textBox3.Text = person.Postnr.ToString();
                    textBox4.Text = person.Postort.ToString();
                    textBox5.Text = person.Telefon.ToString();
                    textBox6.Text = person.Email.ToString();
                }
            }

Czy np o to chodzi?

2

Masz w Visualu taką super opcje jak debugowanie. Wrzuć sobie "kropeczkę" i przeleć linia po linii co zwraca ci listBox1.SelectedItem i na tej podstawie stwórz obiekt.

1

Tak jak @AdamWox wspomniał próbujesz zamienić napis na obiekt.

Napisałeś konstruktor parametrowy
public Person(string name, string gatu, string postnr, string postort, string telefon, string email)

to go użyj. Przekaż w odpowiedniej koleności zawartość tego napisu do konstruktora.

0

Ok dzięki za jakiś punkt odniesienia natomiast w jaki sposób to zrobić nie znam wszystkich komend :(

4

Ustalmy, że ja ci rzucę terminologią i nazewnictwem, a ty sobie za pomocą google poradzisz ;-) Debuggowanie będzie ci potrzebne bardzo często.

0

Surowy nauczyciel z Pana ale spróbuję ewentualnie będę płakał w poduszkę :D

5
AtomBari22 napisał(a):

Ok dzięki za jakiś punkt odniesienia natomiast w jaki sposób to zrobić nie znam wszystkich komend :(

Masz do wyboru:
a) poczytać i się nauczyć
b) nie uczyć się

mam przykrą wiadomość: samo się w głowie nie pojawi.

3

Ogólnie zauważyłem wzrost liczby programistów nie potrafiących czytać oraz korzystać z dobrodziejstw internetu. Nie obrażam Cię kolego w żaden sposób. Wskazuję tylko na fakt pisania tematu zanim spróbujesz rozwiązać go sam. I będziesz miał takie problemy nie tylko na początku. Ja korzystam z googla nawet po ponad 10 latach. To nie jest żaden wstyd. Wstyd to fakt, że debuger krzyczy, że próbujesz typ string przypisać do obiektu Person, a my nie wiemy co odpowiedzieć, bo co mamy powtórzyć to, co jest napisane? W prostych przypadkach jak przekopiujesz wyjątek do googla (dosłownie) znajdziesz w pierwszym linku rozwiązanie. Czyż nie warto? Oszczędzisz sobie naszego biadolenia (bo nie jesteś jedyną osobą która robi takie posty i nie wiem jak inni ale mam wrażenie że piszę z jakimś trollem), a problem rozwiążesz dużo szybciej bez czekania na odpowiedź. Jeżeli problem jest prosty a mimo wszystko nie potrafisz go rozwiązać opisz dodatkowo kroki jakie podjąłeś w rozwiązaniu go samodzielnie. Widząc wtedy Twoje zaangażowanie sam chętnie dam gotowca, ładnie go opiszę i wytłumaczę czemu nie działa. Rozmowa wtedy jest zupełnie inna :) Nie odbieraj tego jako atak, tylko widok z mojej perspektywy 🍻

3

@gswidwa1:

Niedzisiejszy jesteś.

Bo to teraz chodzi o umiejętności miękkie, zamiast samodzielnie rozwiązać problem, ba!, skorzystać z rady to się odszczeknąć bo doradzający nie głaskał po głowie itd ...

3

Zacząłbym od tego że kontrolka ListBox jest nieco niefortunna, chociażby ze względu na to że twoja klasa Person ma kilka pól (własności).
Przemyśl czy nie lepiej użyć ListView , DataGridView.

No ale masz co masz.

ListBox przyjmnie jako item dowolny obiekt a w kontrolce zobaczysz to co zwraca metoda ToString() takiego obiektu.
Twoją klasę Peron nieco bym zmodyfikował i usunął metody CheckEmail (która to jeszcze sypie messageboxem) jak i Register()
Za to przesłoniłbym metodę ToString() dla widoku w kontrolce i późniejszemu zapisowi do pliku.

public class Person
    {
        public string Name { get; set; }
        public string Gatu { get; set; }
        public string Postnr { get; set; }
        public string Postort { get; set; }
        public string Telefon { get; set; }
        public string Email { get; set; }

        public Person(string name, string gatu, string postnr, string postort, string telefon, string email)
        {
            Name = name;
            Gatu = gatu;
            Postnr = postnr;
            Postort = postort;
            Telefon = telefon;
            Email = email;
        }

        public Person(string[] arr)
        {
            Name = arr[0];
            Gatu = arr[1];
            Postnr = arr[2];
            Postort = arr[3];
            Telefon = arr[4];
            Email = arr[5];
        }

        public override string ToString()
        {
            return string.Join(",", this.Name, this.Gatu, this.Postnr, this.Postort, this.Telefon, this.Email);
        }

    }

Pobieranie i zapis z (do) txt.
Myślę że jeden przycisk powinien pobierać dane z pliku -> plik wybierany a nie na sztywno ścieżka w kodzie.
np.

private void TxtFileToListBox()
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.InitialDirectory = "c:\\";
                openFileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
                openFileDialog.FilterIndex = 2;
                openFileDialog.RestoreDirectory = true;

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    string path = openFileDialog.FileName;

                    var fileStream = openFileDialog.OpenFile();

                    listBox1.BeginUpdate();
                    using (StreamReader sr = new StreamReader(fileStream))
                    {
                        while (!sr.EndOfStream)
                        {
                            listBox1.Items.Add(new Person(sr.ReadLine().Split(',')));
                        }
                    }
                    listBox1.EndUpdate();
                }
            }
        }

Drugi przycisk zapisujący plik, też w dowolne miejsce i o dowolnej nazwie.
np

private bool ListBoxItemsToTxt()
        {
            SaveFileDialog save = new SaveFileDialog();

            save.FileName = "BazaListBox.txt";

            save.Filter = "Text File | *.txt";

            if (save.ShowDialog() == DialogResult.OK)

            {
                StreamWriter writer = new StreamWriter(save.OpenFile());
                for (int i = 0; i < listBox1.Items.Count; i++)
                {
                    writer.WriteLine(((Person)listBox1.Items[i]).ToString()); 
                }
                writer.Dispose();
                writer.Close();
                return true;
            }
            else { return false; }
        }

A sama manipulacja: usuwanie, edytowanie, dodawanie elementów listy odbywa się tylko w ListBox

przykładowo mogło by wyglądać to tak:

public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }


        private void Avslutaknap_Click(object sender, EventArgs e)
        {
            this.Close();
        }


        private void ClearTextBoxes()
        {
            textBox1.Clear();
            textBox2.Clear();
            textBox3.Clear();
            textBox4.Clear();
            textBox5.Clear();
            textBox6.Clear();
        }

        private void Rensaknap_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            ClearTextBoxes();
        }

        private void TxtFileToListBox()
        {
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
            {
                openFileDialog.InitialDirectory = "c:\\";
                openFileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
                openFileDialog.FilterIndex = 2;
                openFileDialog.RestoreDirectory = true;

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    string path = openFileDialog.FileName;

                    var fileStream = openFileDialog.OpenFile();

                    listBox1.BeginUpdate();
                    using (StreamReader sr = new StreamReader(fileStream))
                    {
                        while (!sr.EndOfStream)
                        {
                            listBox1.Items.Add(new Person(sr.ReadLine().Split(',')));
                        }
                    }
                    listBox1.EndUpdate();
                }
            }
        }



        private bool ListBoxItemsToTxt()
        {
            SaveFileDialog save = new SaveFileDialog();

            save.FileName = "BazaListBox.txt";

            save.Filter = "Text File | *.txt";

            if (save.ShowDialog() == DialogResult.OK)

            {
                StreamWriter writer = new StreamWriter(save.OpenFile());
                for (int i = 0; i < listBox1.Items.Count; i++)
                {
                    writer.WriteLine(((Person)listBox1.Items[i]).ToString()); 
                }
                writer.Dispose();
                writer.Close();
                return true;
            }
            else { return false; }
        }

        private void Ladda_uppknap_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            TxtFileToListBox();
        }

        private void Sökknap_Click(object sender, EventArgs e)
        {
             string FindName = textBox7.Text.ToLower();
            var pr = (from Person p in listBox1.Items where p.Name.ToLower() == FindName select p).FirstOrDefault();
            if(pr != null)
            {
                listBox1.SetSelected(listBox1.Items.IndexOf(pr), true);
            }
            else
            {
                MessageBox.Show("Brak Nazwy na liście");
            }
        }

        private void RegisteraknapEdit_Click(object sender, EventArgs e)
        {
            if(ValidatingTextBoxes())
            {
                if (listBox1.SelectedIndex >= 0)
                {
                    listBox1.Items[listBox1.SelectedIndex]= new Person(textBox1.Text, textBox2.Text, 
                        textBox3.Text, textBox4.Text, textBox5.Text,textBox6.Text);
                }
                else
                {
                    MessageBox.Show("Zaznacz element na liście");
                }
            }
            else
            {
                MessageBox.Show("Błąd danych");
            }
        }

        private void Registeraknap_New_Click(object sender, EventArgs e)
        {
            if (ValidatingTextBoxes())
            {
                listBox1.Items.Add(new Person(textBox1.Text, textBox2.Text, textBox3.Text, textBox4.Text, textBox5.Text,
                textBox6.Text));
                ClearTextBoxes();
            }
            else
            {
                MessageBox.Show("Błąd danych");
            }
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            Person selectedPerson = (Person)listBox1.SelectedItem;
            if(selectedPerson != null)
            {
                textBox1.Text = selectedPerson.Name;
                textBox2.Text = selectedPerson.Gatu;
                textBox3.Text = selectedPerson.Postnr;
                textBox4.Text = selectedPerson.Postort;
                textBox5.Text = selectedPerson.Telefon;
                textBox6.Text = selectedPerson.Email;
            }
        }

        private bool ValidatingTextBoxes()
        {
            return textBox1.Text.Length > 0 && textBox2.Text.Length > 0 && 
                textBox3.Text.Length > 0 && textBox4.Text.Length > 0 && 
                textBox5.Text.Length > 0 && textBox6.Text.Length > 0 && Email_Valid(textBox6.Text);
        }

        private bool Email_Valid(string sAddress)
        //metoda weryfikująca poprawnośc adresu email
        {
            return System.Text.RegularExpressions.Regex.IsMatch(sAddress, @"^[\w-\.]+@([\w-]+\.)+[A-Za-z]{2,3}$");
        }

        private void Gem_filen_Click(object sender, EventArgs e)
        {
            ListBoxItemsToTxt();
        }

       
    }

Przeanalizuj dokładnie i postaraj się zrozumieć powyższy szablon, nawet gdyby miało to zająć 50h
A później popraw po swojemu

pozdr

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