Zamykanie formatki wysłanej jako object sender

0

Witam! Mam formatkę, w której tworzę obiekt będący nową formatką:

private void Form_Load(object sender, EventArgs e)
        {
            this.Enabled = false;

            Form2 f = new Form2 ();
            f.LoggingSucced += new LoggingEvents.LoggingSuccedEventHandler(LoggingSucced_Handler);
            f.Show();

        }

Potem łapię event:

private void LoggingSucced_Handler(object sender, LoggingEventArgs e)
        {
            Form2 f2 = (Form2)sender;
            f2.Close();
        }

Może ktoś wytłumaczyć dlaczego zamykanie tej formatki nie działa? Podejrzewam, że chodzi o zmienne lokalne.

0

a co to jest LoggingSucced, LoggingSuccedEventHandler i jak jest wywoływany?

0

LoggingSucced to event, który wsytępuje w formatce Form2 po pomyślnym zalogowaniu na serwer.

0

_
kod, KOD, KOD, <font size="100">KOD</span>

0
public partial class LogInForm : Form
    {
        #region Properties
        private Client client;
        public Client Client { get { return client; } set { client = value; } }
        #endregion

        #region Events
        public event LoggingEvents.LoggingSuccedEventHandler LoggingSucced;
        public event LoggingEvents.LoggingFailedEventHandler LoggingFailed;
        #endregion

        #region Constructor
        public LogInForm()
        {
            InitializeComponent();
        }
        #endregion

        #region Protected Methods

        protected void OnLoggingSucced(LoggingEventArgs e)
        {
            if (LoggingSucced != null)
            {
                LoggingSucced(this, e);
            }
        }

        protected void OnLoggingFailed(LoggingEventArgs e)
        {
            if (LoggingFailed != null)
            {
                LoggingFailed(this, e);
            }
        }

        #endregion

        #region Private Methods
        private void buttonLogIn_Click(object sender, EventArgs e)
        {
            
            if (this.textBoxNickname.Text == "")
            {
                MessageBox.Show("Nickname cannot be empty!");
            }
            else if (this.textBoxPort.Text.Length != 4)
            {
                MessageBox.Show("Port has to have 4 numbers!");
            }
            else
            {
                try
                {
                    int i;
                    Int32.TryParse(this.textBoxPort.Text, out i);
                    try
                    {
                        this.Client = new Client(this.textBoxNickname.Text);
                        this.Client.ConnectToTheServer(IPAddress.Parse(textBoxServerIp.Text), Int32.Parse(textBoxPort.Text));
                        this.Client.CommandReceived += new CommandEvents.CommandReceivedHandler(CommandReceived_Handler);
                        this.Client.CommandFailedSent += new CommandEvents.CommandFailedSent(CommandFailedSent_Handler);
                        this.Client.ClientDisconnected += new ClientEvents.ClientDisonnectedHandler(ClientDisconnected_Handler);
                        this.Client.LogIn();                        
                    }
                    catch (Exception ex)
                    {
                      MessageBox.Show("Cannot access server! " + ex.Message);
                    }
                
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Port has to have 4 numbers! " + ex.Message);
                }
            }
        }

        private void CommandReceived_Handler(object sender, CommandEventArgs e)
        {
            this.Client.CommandReceived -= new CommandEvents.CommandReceivedHandler(CommandReceived_Handler);

            switch (e.Command.CommandType)
            {
                case Commands.CommandType.LogginSucced:
                    {
                        OnLoggingSucced(new LoggingEventArgs(e.Command.CommandText, this.client));
                        RemoveEventsFromClient();
                        break;
                    }
                case Commands.CommandType.LogginFailed:
                    {
                        OnLoggingFailed(new LoggingEventArgs(e.Command.CommandText, this.client));
                        break;
                    }
            }
        }

        private void CommandFailedSent_Handler(object sender, EventArgs e)
        {
            OnLoggingFailed(new LoggingEventArgs("Logging failed!", this.client));
        }

        private void ClientDisconnected_Handler(object sender, ClientEventArgs e)
        {
            OnLoggingFailed(new LoggingEventArgs(e.Message, e.Client));
        }
        
        
        private void buttonCancel_Click(object sender, EventArgs e)
        {
            OnLoggingFailed(new LoggingEventArgs("Logging has been cancelled", this.client));
        }

        private void RemoveEventsFromClient()
        {
            this.client.ClientDisconnected -= ClientDisconnected_Handler;
            this.client.CommandFailedSent -= CommandFailedSent_Handler;
            this.client.CommandReceived -= CommandReceived_Handler;
           /* if (this.client.CommandSucceedSent != null)
            {
               //
            }*/
        }

        #endregion


    }
}
0

jesteś pewien, że LoggingSucced_Handler jest wywoływane? - postaw tam breakpointa i zobacz czy wchodzi. Jeśli wchodzi to zobacz jaką wartość ma sender

0

tak, jest wykonywane..

0

Czy ten kod jest taki jaki masz? Tutaj masz Form2:

Form2 f = new Form2 ();

A tutaj już LogInForm:

public partial class LogInForm : Form

Dlaczego LogInForm nie może się sama zamykać?

0

rzeczywiscie tam gdzie

Form2 

powinno być LogInForm

, ale to nie jest problem.
0

Nie dostajesz jakiegoś wyjątku? Zdebuguj z opcją, żeby zatrzymywał się również na złapanych wyjątkach. Zakładam, że nie masz podpiętego anulowania zamykania w OnFormClosing

EDIT:
Ten Client nie implementuje przypadkiem IDisposable? Ja bym sprawdził, czy nie trzeba zwolnić jego zasobów. To na marginesie.

0

w internecie znalazlem cos takiego :

 f2.Invoke((MethodInvoker)(() => f2.Close()));

i to działa, tylko, że nie wiem co to robi...

0

https://msdn.microsoft.com/pl-pl/library/system.windows.forms.form.invoke%28v=vs.110%29.aspx

Invoke wykorzystuje się w wielowątkowej aplikacji. U ciebie nie widzę tworzenia wątków, więc powinno działać bez tego...

0

Właśnie, że w w Client.cs w funkcji LogIn mam odpalenie BackgroundReceiver'a , który jest polem w Client i chodzi w pętli nieskonczonej

while(true){ i odbiera wiadomosc zalogowania }
0
        public void ConnectToTheServer(IPAddress serverIp, int port)
        {
            this.socket.Connect(new IPEndPoint(serverIp, port));
            this.networkStream = new NetworkStream(this.socket);
        }

        public void LogIn()
        {
            RunReceiver();
            SendCommand(new Command(CommandType.LogIn, this.nickname, this.Ip, this.ServerIp));
        }

 private void RunReceiver()
        {
            bgWorkerReceiver = new BackgroundWorker();
            bgWorkerReceiver.WorkerSupportsCancellation = true;
            bgWorkerReceiver.DoWork += new DoWorkEventHandler(StartReceiving);
            bgWorkerReceiver.RunWorkerAsync();
        }
 
0

To wygląda tak jak on po wejściu w Client.cs
w funkcji

 private void StartReceiving(object sender, DoWorkEventArgs e)
        {
            while (this.Connected)
            {

                byte[] cmdType = new byte[sizeof(int)];
                if (ReadFromNetworkStream(cmdType, 0, sizeof(int)))
                { break; }

                byte[] targetSize = new byte[sizeof(int)];
                if (ReadFromNetworkStream(targetSize, 0, sizeof(int)))
                { break; }

                byte[] target = new byte[BitConverter.ToInt32(targetSize, 0)];
                if (ReadFromNetworkStream(target, 0, BitConverter.ToInt32(targetSize, 0)))
                { break; }

                byte[] cmdSize = new byte[sizeof(int)];
                if (ReadFromNetworkStream(cmdSize, 0, sizeof(int)))
                { break; }


                byte[] cmdText = new byte[BitConverter.ToInt32(cmdSize, 0)];
                if (ReadFromNetworkStream(cmdText, 0, BitConverter.ToInt32(cmdSize, 0)))
                { break; }

                Command command = new Command(cmdType, cmdText, this.Ip, target);
                this.OnCommandReceived(new CommandEventArgs(command));
            }
            OnClientDisconnected(new ClientEventArgs("Client disconnected!", this));
        }

wchodzi w OnCommandReceived, ale po debugowaniu widzę ze on nigdy tam już nie wraca, tylko idzie do handlera CommandReceived_Handler , a potem wchodzi w LoginSucced_Handler i nie wraca.... może to jest powodem, że zrobiłem jako w tym wątku przejście do miejsca poza tę formatkę bo odpalany jest LoginSucceed_Handler. Nie wraca i potem juz nie moge odebrac zadnej waidomości majac obiekt CLient w innej Formatce. Zrobiłem Eventy bo on własnie odbiera w tle te wiadomości, bo cchiałem wiedzieć czy pomyślnie zalogowano. Macie jakieś pomysły co z tym zrobić?

0

W WinFormsach niedozwolone jest wywoływanie między wątkowe. W normalnym trybie możesz wywoływać metody tylko z wątku, w którym formatka została utworzona. W przeciwnym wypadku dostaniesz wyjątek (pewnie leciał i pewnie gdzieś go złapałeś). Rozwiązaniem jest wykorzystywanie właśnie Invoke.

Co do "wracania" - to musi wracać. Sprawdź w menu Debug->Exceptions czy masz zaznaczone "thrown" przy Common Language Runtime Exceptions

0

Dostaję coś takiego:

Cross-thread operation not valid: Control 'LogInForm' accessed from a thread other than the thread it was created on.
 

chyba to o czym mówisz

0

jeżeli ten watek został odpalony w Formatce LogInForm, to w formatce ClientForm zawsze będę musiał używać invoke do odbierania CommandReceived_Handler?

0

Nie jestem ekspertem od WinFormsów (bawiłem się tym jedynie na studiach), ale na to wychodzi.

2

NIE - Invoke i InvokeRequired (poczytać) jest wymagany wtedy, kiedy odwołujesz się do wątku głównego (w szczególności do elementów GUI) z innego wątku. To czy odwołanie jest z innego wątku musisz wiedzieć Ty jako programista.

0

ok dzięki! Teraz już rozumiem.. wszystko jasne!

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