Jedna událost pro zachycení více událostí   otázka

VB.NET

Zdravím všechny místní hlavouny.

Potřebuji poradit jak si ulehčit práci při následující situaci.

Potřebuji vyhodnotit před opuštěním formuláře zda nedošlo ke změně hodnoty v některém z textboxů, maskedtexboxů, datatimepickerů apod. Těchto prvků je dohromady cca. 50. Existuje nějaká možnost jak událost o změně zpracovat hromadně. Jde mi o to, aby při opuštění formuláře došlo k vyhodnocení zda došlo ke změně a zda se tedy provede update dat do databáze.

Chci se tak vyhnout třem věcem, aby nedošlo ke ztrátě změněnných dat, aby se databáze neaktualizovala pokud si uživatel data jen prohlížel a neudělal žádnou změnu a aby se DB aktualizovala jen jednou a ne při změně jednotlivých komponent.

Stačí mi aspoň nějaká idea jak to řešit co nejjednodušeji.

Předem díky

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nějakým způsobem musíte mít seznam prvků, ze kterých načítáte hodnoty, které pak do databáze ukládáte. Jedna z možností je mít samostatný objekt reprezentující informace na formuláři, který si sám vnitřně kontroluje, jestli byl změněn. V každé vlastnosti kotrolujete, zda se hodnota změnila a pokud ano, nastavíte nějaký příznak určující změnu objektu proti původnímu stavu. Tady se dá formulář navázat na objekt pomocí bindingu.

Pokud se však jedná o hotové řešení a nechcete jej celé přepisovat, můžete si napsat metody, které předáte různé prvky a ona je zaznamená společně s jejich hodnotou. Před zavřením formuláře pak projdete tento seznam a porovnáte s hodnotou uloženou při inicializaci. Pokud se nebude alespoň v jednom případě shodovat, víte, že bylo něco změněno. Implementaci musíte provést pro každý typ vstupního objektu (zvlášť pro textboxy, zvlášť pro checkboxy atp.).

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Nejlepší je na událost Validated u daných ovládacích prvků navěsit změnu nějaké Boolean proměnné a tu potom při zavírání okna kontrolovat. Validated a ne například TextChanged proto, protože TextChanged nastává i při programové změně (ne uživatelské) textu a navíc na Validated je zajištěno, že kontrola správnosti dat již proběhla ve Validating.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Díky oboum za nakopnutí :-)

Událost Validated má nevýhodu, že probíhá i bez změny dat, stačí že ztratí fokus. Na základě toho je dost obtížné sledovat změny. Jedině si pamatovat hodnotu před enterem a pak ji porovnat po validaci. Což ale věc spíš komplikuje

Nakonec jsem to "zbastlil" takhle. Pomocí boleánů si sleduji stavy zda je form už nahrán, aby neprobíhali kontroly změn během nahrání a pak teprve zda se změnili hodnoty. V kódu níže tedy uvádím pouze jak se vyřešil průchod a přidání údalostí bez nutností to dělat sepárátně pro každý prvek. Pozn. Formulářové controls mám na panelech takže nejdřív musím projít kolekcí panelů. Třeba Vás napadne jednodušší řešení, ale hlavně že mi to funguje :-)

Private Sub f_Dispatch_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        IsDataChange = False
        IsLoad = False
        
Dim txb As TextBox
        Dim mtxb As MaskedTextBox
        Dim nud As NumericUpDown
        Dim cbx As CheckBox
        Dim dtp As DateTimePicker
        For Each pnl As Control In Me.Controls
            If TypeOf pnl Is Panel Then
                For Each ctr As Control In pnl.Controls
                    Select Case True
                        Case TypeOf ctr Is TextBox
                            txb = ctr
                            AddHandler txb.TextChanged, AddressOf ControlChange
                        Case TypeOf ctr Is MaskedTextBox
                            mtxb = ctr
                            AddHandler mtxb.TextChanged, AddressOf ControlChange
                        Case TypeOf ctr Is NumericUpDown
                            nud = ctr
                            AddHandler nud.ValueChanged, AddressOf ControlChange
                        Case TypeOf ctr Is CheckBox
                            cbx = ctr
                            AddHandler cbx.CheckStateChanged, AddressOf ControlChange
                        Case TypeOf ctr Is DateTimePicker
                            dtp = ctr
                            AddHandler dtp.ValueChanged, AddressOf ControlChange
                    End Select
                Next
            End If
        Next
        IsLoad = True
    End Sub
    Private Sub ControlChange()
        If IsDataChangeMode Then
            IsDataChange = True
        End If
    End Sub

nahlásit spamnahlásit spam 2 / 2 odpovědětodpovědět

Například TextBox má ještě vlastnost Modified, která udává, jestli byl text uživatelsky změněn a to se dá použít spolu s Validated.

nahlásit spamnahlásit spam 2 / 2 odpovědětodpovědět

Ideu Vám dám - použijte LINQ to SQL. Tam je detekce změněných hodnot ve formulářích řešena interně, resp. pomocí SendPropertyChanged. Obrovská výhoda je ta, že kód je Vám vygenerován Visual Studiem, tzn. všechny ty otravnosti ve smyslu

	Public Property POZNAMKA() As String
		Get
			Return Me._POZNAMKA
		End Get
		Set
			If (String.Equals(Me._POZNAMKA, value) = false) Then
				Me.OnPOZNAMKAChanging(value)
				Me.SendPropertyChanging
				Me._POZNAMKA = value
				Me.SendPropertyChanged("POZNAMKA")
				Me.OnPOZNAMKAChanged
			End If
		End Set
	End Property

nemusíte psát, ale dostanete je hotové.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Bohužel v práci SQL server k dispozici nemám, takže musím ukládat do mdb,což mě taky mrzí. Takže tudy cesta nevede. Přesto děkuji

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Je možné při natažení formuláře (událost Load) uložit do vlastnosti Tag ovl.prvků původní hodnotu a při uzavírání formuláře zkontrolovat, zda hodnota ovl.prvku (vlastnost Text) je stejná, anebo se u některého prvku liší.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback