Niezrozumiałe zachowanie zmiennej

0

Cześć!

Piszę sobie krótki programik i nie mogę zrozumieć pewnego mechanizmu.
Otóż w jednym usercontrol mam pole o nazwie imie.
W związku z tym w formie zrobiłem wpis:
string LokalneImie;
usercontrol u1 = new usertconstrol();
LokalneImie = u1.imie;

Kompiluje, działa. Zamykam VS, odpalam, znów kompiluje - nie działa.
Wrzucam MessageBox, żeby wyświetliło zawartość zmiennej = null...

Jakiś pomysł?

0
Trzeźwy Mleczarz napisał(a):

Cześć!

Piszę sobie krótki programik i nie mogę zrozumieć pewnego mechanizmu.
Otóż w jednym usercontrol mam pole o nazwie imie.
W związku z tym w formie zrobiłem wpis:
string LokalneImie;
usercontrol u1 = new usertconstrol();
LokalneImie = u1.imie;

Kompiluje, działa. Zamykam VS, odpalam, znów kompiluje - nie działa.
Wrzucam MessageBox, żeby wyświetliło zawartość zmiennej = null...

Jakiś pomysł?

Może podaj więcej kodu?

mr-owl

0

Tak mam jeden pomysł. Wrzuć więcej kodu. Kod też przeklej, bo to co napisałeś się nie skompiluje.

0

Właściwie wiele tego nie ma, ale proszę bardzo:

UserControl

        void button1_Click(object sender, EventArgs e)
        {
            imie = "janek";//textBox1.Text;  // dla testów czy w ogóle przechodzi cokolwiek wstawiłem na sztywno, ale też nic
            try
            {
                  //zapis_do_bazy_danych;
            }
            catch
            {

            }
            this.Dispose();
        }

Form1

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            TimerPiosenek.Start();
        }

        string imie;
        
        private void TimerPiosenek_Tick(object sender, EventArgs e)
        {
            zbieracz z = new zbieracz();
            imie = z.imie;
            MessageBox.Show(imie);

            try
            {
                   update_danych_w_bazie, jeżeli imie = "Podana_wartość";
            }
            catch
            {

            }
        }
0

UserControl nazywa się zbieracz, moje niedopatrzenie przy wklejaniu kodu.

0

mimo kodu nadal jest niejasne co Ty na tam robisz.

0

Nie wiem czy tylko ja ale nic z tego nie rozumiem, co chcesz osiągnąć?

0

Jak mogę jaśniej opisać fakt, że w userControl ( zbieracz ) pobieram imię, a później przekazuję je do Form i wyświetlam w MessageBox?
Póki co nic więcej nie chcę zrobić. Kilka razy to się udało, po zrestartowaniu VS przestało.
Ogólnie zamysł jest taki, że jak userControl dostanie imie to zapisuje je do bazy.
Następnie w Formie uzytkownik otwiera plik i w bazie robi się update rekordu, który ma jego imie, gdzie w polu plik wpisywana jest nazwa uruchomionego pliku.
Nic więcej dlatego właśnie potrzebuję wyciągnąć imię z userControl do Formy.

0

Ale do czego Ci tutaj jest potrzebny UserControl?

0

Taki mam wymóg, że muszę w programie użyć userControl i dlatego akurat w tym miejscu mi pasowało :)

0

W taki razie chyba nie rozumiem do czego służy UserControl, myślałem że do tego by zamknąć sobie pewny wygląd kilku kontrolek i używać tego jako całości a tutaj mam generować nowy UserControl co Tick mojego Timera nawet nie podpinając całości do formy a dodatkowo wyświetlam MessageBox... super...

0

Ok, wstawienie userControl do Ticka jest błędem, więc to poprawię, ale nie o to chodziło w moim pytaniu.
Czy mógłbyś podpowiedzieć, jak przenieść dane z userControl do Formy?
Poza tym moja kontrolka jest w formie komunikaty, wykorzystująca kilka innych kontrolek, więc zgadza się to z tym co napisałeś.

0

Po stworzeniu UserControl powinna pojawić Ci się w ToolBox-ie, przeciągasz to na formatkę, umieszczasz tam gdzie Ci potrzeba, nadajesz nazwę i teraz w formie używasz jej nazwy i nazw kontrolek by dostawać się do poszczególnych pól.

1

this.Dispose() - wtf? Wiesz, co robi ta metoda? Jeśli nie, to poszukaj opisu i przeczytaj go, a potem zastanów się, dlaczego nigdy nie powinno się jej wołać z obiektu ją implementującego (czyli właśnie this.Dispose()).

0

Faktycznie mój błąd, nie wiem czemu chciałem ją deklarować, a nie po prostu odwoływać się do pól.
Dziękuję za pomoc!

0
ŁF napisał(a):

this.Dispose() - wtf? Wiesz, co robi ta metoda? Jeśli nie, to poszukaj opisu i przeczytaj go, a potem zastanów się, dlaczego nigdy nie powinno się jej wołać z obiektu ją implementującego (czyli właśnie this.Dispose()).

Masz na myśli odzyskiwanie pamięci? A to nie jest tak, że garbage collector i tak się tym zajmie?
Zamieniłem na Dispose(true) - może być? :)

1

Poczytaj... I przeczytaj powoli i ZE ZROZUMIENIEM mój poprzedni post.
Dispose woła się przy tylko usuwaniu obiektu, jako ostatnie odwołanie do obiektu przed straceniem referencji do niego. Obiekt nigdy nie usuwa sam siebie.
Być może .Dispose pomyliło Ci się z GC.Collect, której to metody też nie powinieneś nigdy wywoływać. Poczytaj o tym, jak działa GC w .net, bo to co teraz usiłujesz robić to tzw. premature optimization, czyli niepotrzebne optymalizacje w złych miejscach robione nieprawidłowym kodem,

0

Ok, dzięki za zwrócenie uwagi, poczytam o tym na pewno.
A samo .Dispose() zamienię na this.Hide().

0

Mam jeszcze jedno pytanko w temacie. Gdy kontrolka jest na formie to odwołuję się do niej bezpośrednio jak do każdej innej. A jak to zrobić z innej klasy? Przykładowo kontrolka jest publiczna, z publicznymi polami na formie i pobiera dane, jak w powyższym przypadku, ale jest inna klasa, która też chcę te dane.

0

Może od razu zdradź swój poziom znajomości programowania bo tutaj podstawy się kłaniają

0

Witam,

UserControl zawiera 2 pola TextBox (txtSource, txtDestination) i Button (btnSend):

namespace WinFormsUserControlSample
{
    using System;
    using System.Windows.Forms;

    public partial class PanelUserControl : UserControl
    {
        public PanelUserControl()
        {
            this.InitializeComponent();
        }

        public delegate void ChangeSourceDelegate(StringEventArgs e);

        public ChangeSourceDelegate ChangeSourceDelegateInstance;

        public string Destination
        {
            set { this.txtDestination.Text = value; }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (ChangeSourceDelegateInstance != null)
            {
                ChangeSourceDelegateInstance(new StringEventArgs(this.txtSource.Text));
            }
        }
    }
}

teraz twoja główna formatka (MainForm) zawiera dwie instancje UserControl (LeftPanel, RightPanel):

namespace WinFormsUserControlSample
{
    using System.Windows.Forms;

    public partial class MainForm : Form
    {
        public MainForm()
        {
            this.InitializeComponent();

            this.leftPanel.ChangeSourceDelegateInstance += e =>
            {
                this.rightPanel.Destination = e.Value;
            };

            this.rightPanel.ChangeSourceDelegateInstance += e =>
            {
                this.leftPanel.Destination = e.Value;
            };
        }
    }
}

Teraz gdy zmienię zawartość pola tekstowego oznaczonego jako Source w pierwszej instancji UsetControl i kliknę przycisk Send zawartość pola Destination w drugiej instancji UserControl zmieni się. Druga instancja UserControl działa analogicznie

Dane przesyłane są zewnętrzną klasą

namespace WinFormsUserControlSample
{
    using System;

    public sealed class StringEventArgs : EventArgs
    {
        public string Value { get; private set; }

        public StringEventArgs(string value)
        {
            this.Value = value;
        }
    }
}

Pozdrawiam,

mr-owl

0

Ok, troszkę to trwało, ale moja wiedza na temat zdarzeń sprowadzała się do tego, że wiedziałem, że istnieją i tyle, więc teraz musiałem to w miarę zrozumieć.
Na podstawie Twojego kodu oraz danych w sieci zrobiłem sobie coś takiego:

W kontrolce

 namespace Delegaty
{
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }

        public delegate void MojWlasnyDelegat(UstawDane e);

        public event MojWlasnyDelegat OnMojWlasnyDelegat;

        private string imie
        {
            set { this.textBox1.Text = value; }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (OnMojWlasnyDelegat != null)
            {
                OnMojWlasnyDelegat(new UstawDane(this.textBox1.Text));
            }
        }
    }

    public sealed class UstawDane : EventArgs
    {        
        public string Wartosc { get; set; }

        public UstawDane(string wartosc)
        {
            this.Wartosc = wartosc;
        }
    }
}

W Formie

     public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            this.userControl1.OnMojWlasnyDelegat += e => { label1.Text = e.Wartosc; };
        }
    }

Ogólnie wszystko działa, tylko nie do końca mogę pojąć zapis w formie.
Czy chodzi o to, że w parametrze e robię sprzężenie label1.Text i e.Wartosc?
W którą stronę to działa i jak?
Popraw mnie, jeśli się mylę:
OnMojWlasnyDelegat przechoduje "zapisy" na event i gdy kliknę przycisk to właśnie zapisani w nim subskrybenci są informowani o zdarzeniu.

0

Witam,

W UserControl dodałem Property które daje mi dostęp do pola Text z TextBox-a

Pozdrawiam,

mr-owl

0

A co źle robię, jak z innej klasy chciałbym dopisać się do listy sukskrybentów, ale mam błąd:
Element „UserControl1.MojWlasnyDelegat” to element typ, ale jest używany jak element zmienna

Kod napisałem taki:

namespace Delegaty
{
    public class MyObject
    {
        string imie;
        public void WezSobieImie(UserControl1 UstawDane)
        {
            UserControl1.MojWlasnyDelegat += e => { imie = e.value; };
        }
    }
}
0

Ale co Ty chcesz osiągnąć?

0

Chcę pobrać dane zarówno do Form1 jak i do innej klasy, na przykład ZapisDanych ( no bo skoro to zdarzenie to każda klasa, która jest podpięta i czeka na info to powinna móc je dostać, tak? ).
Do Formy pobiera ładnie, ale do ZapisDanych nie mogę.

0

Witam,

To dla twojej drugiej klasy która ma odpowiadać za zapisywanie danych przekazuj dane wywołując jakąś funkcję która realizuje tylko to co od niej oczekujesz,

public sealed MojaBazaDanych
{
    public void Save(string dane)
    {
        //robie coś z danymi
    }
}

teraz w gdzieś dodajesz sobie swoją klasę która odpowiada za przechowywanie danych

var mbd = new MojaBazaDanych();
mdb.Save("moje dane");

Nie rozumiem dlaczego chcesz do swojej dodatkowej klasy przekazywać UserControl zamiast gołych danych

Pozdrawiam,

mr-owl

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