» »

[VB] datagridview

[VB] datagridview

korenje3 ::

A mogoee ve kako bi lahko dodal random id v datagridview oziroma bindano bazo za vsak manjkajoe ID.
Trenutno imam takole:

    Sub updatelist()
        ' update sql

        For Each row As DataRow In fxts.datasetu.Tables("users").Rows
            If String.IsNullOrEmpty(row("hash").ToString()) = True Then
                row("hash") = System.Guid.NewGuid().ToString()
            End If
        Next
        Try
            adapter_users.Update(fxts.datasetu.Tables("users"))
        Catch ex As Exception
            fxts.infobox("SQL: " + ex.Message.ToString)
        End Try
    End Sub


v zaeetku forma bindam:

    Private Sub userdb_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        DataGridView1.DataSource = fxts.datasetu.Tables("users")

        If DataGridView1.RowCount = 0 Then
            reloadlist()
        End If
    End Sub


V glavnem problem je, ee zbri^1em celice, mi javi napako v for each rutini.
Kako narediti da bo to funkcioniralo.
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

cekr ::

Kot prvo ti svetujem, da se posloviš od dataseta. To je povozil čas.

Začni uporabljat Linq.

Ni tudi ravno fajn programsko pisat v Grid. Bolje, da to urediš že v sourcu.

Naredi si nek Class, ki vsebuje vse property-e, ki jih želiš videti kot stolpce. Lahko tudi kakšnega skritega(npr. Id).

Potem pa samo for next,
vmes pa napolni vsak class s podatki.
Posamezen Class pa dodaj v listo.

Nazadnje pa listo obesi na na Grid.

Namesto List lahko še raje uporabi kakšen Collection ali ObservableCollection, ki omogoča spreminjanje vredosti in sproža dogodke.

Upam, da sem te prav razumel, kaj hočeš.
Sinclair ZX Spectrum [Zilog Z80A - 3.5 MHz, 48kB, dvojni kasetofon,
TV-OUT, radirke, Sinclair-Basic], Sinclair ZX-81 [Z80A, 3.25MHZ, 1kB]

korenje3 ::

Bom ostal pri dataset.

Rad bi dodal nek unikaten id v "hash" column za vsak nov stoplec.
še najbolje bi bilo če bi to lahko naredil v času ko sql to zapiše...

adapter_users.InsertCommand.Parameters.Add("@hash", MySqlDbType.VarChar, 36, "hash")
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

korenje3 ::

evo sm že pogruntu...

    Sub updatelist()
        ' update sql
        For Each row As DataRow In fxts.datasetu.Tables("users").Rows
            If row.RowState <> DataRowState.Deleted Then
                If String.IsNullOrEmpty(row("hash").ToString()) = True Then
                    row("hash") = System.Guid.NewGuid().ToString()
                End If
            End If
        Next
        Try
            adapter_users.Update(fxts.datasetu.Tables("users"))
        Catch ex As Exception
            fxts.infobox("SQL: " + ex.Message.ToString)
        End Try
    End Sub
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

korenje3 ::

Imam še eno vprašanje.

Imam vklopljen:
datagridview1.EditMode = DataGridViewEditMode.EditOnEnter

Kako bi naredil, da v primeru več izbranih celic izklopim edit mode zadnje celice (v stilu excela).
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

cekr ::

Če je multiselect vklopljen in imaš označenih več polj, itak ne moreš vpisovat.

Lahko pa nadziraš,koliko polj je selektiranih, in ob >1, izklopiš edit.
Sinclair ZX Spectrum [Zilog Z80A - 3.5 MHz, 48kB, dvojni kasetofon,
TV-OUT, radirke, Sinclair-Basic], Sinclair ZX-81 [Z80A, 3.25MHZ, 1kB]

korenje3 ::

gledam tole...
http://msdn.microsoft.com/en-us/library...

A obstaja kakšna možnost, da se nariše obrobo trenutne celice, brez da poruši prikaz izbrane celice pri odprtju okna z datagridview1.
torej recimo da nariše kvadrat s tem da ostane vse enako kot bi bilo sicer.
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

cekr ::

Razumeti moraš, kako je sestavljen GridView.
Če boš prišel toliko globoko, da boš overridal osnovni element, boš lahko postoril karkoli, kar ti omogoča osnovni element.Recimo, da je to TextBox. Določiš mu border in si rešen. Seveda, če boš sploh smel posegati tako globoko.
Seveda pa nimaš toliko prostih rok kot pri WPF.

Boš pa moral paziti, da se ti vedno, ko izgubi focus, posatvi nazaj na nulto pozicijo.
Sinclair ZX Spectrum [Zilog Z80A - 3.5 MHz, 48kB, dvojni kasetofon,
TV-OUT, radirke, Sinclair-Basic], Sinclair ZX-81 [Z80A, 3.25MHZ, 1kB]

korenje3 ::

Jaz imam barvanje v DataGridView1.CellPainting dogodku.
Problem je ko skrijem okno in potem ponovno prikažem, mi selektirana celica zgine dokler se ne premaknjem iz nje.

Problem je tudi pri spreminjanju širine columna. Črte se poznajo v selektirani celici (ki naj bi jo barval). Če rišem izven fokusa celice, ostane tisto narisno kljub temu da grem ven iz te celice.

je mogoče edina rešitev z invalidate fukcijo?
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

korenje3 ::

Zanima me še to...

Če dodam neke kolone v lokalno bazo. Zakaj moram potem v datagridview dodajat nove kolone, da jim lahko določim parametre in obliko?

Recimo imam tako:
Public c_active As New DataGridViewCheckBoxColumn() With {.Name = "Active", .DataPropertyName = "Active", .ValueType = System.Type.GetType("System.UInt16", .TrueValue = 1, .FalseValue = 0)}
Public c_columns As New ArrayList({c_active})

            For Each column In c_columns
                .Columns.Add(column.datapropertyname)
                .Columns(column.datapropertyname).datatype = column.valuetype
            Next

       With DataGridView1
            .DataSource = fxts.datasetu.Tables("users")
end with

      DataGridView1.Columns.Add(fxts.c_active)

        With fxts.c_active
            .Width = 45
            .Frozen = True
            .Resizable = DataGridViewTriState.False
            .ToolTipText = "Enable trading on this account"
            .DisplayIndex = 0
            .TrueValue = 1
            .FalseValue = 0
        End With
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

Zgodovina sprememb…

  • spremenil: korenje3 ()

korenje3 ::

Izgleda da mi program zatrokira že tukaj:

       With datasetu.Tables("users")
            For Each column In c_columns
                infobox(column.ToString)
                .Columns.Add(column)
                '.Columns(column.datapropertyname).datatype = column.valuetype
            Next


Če uporabim .Columns.Add(column.datapropertyname), potem dela normalno s tem da mi ne prenese nobenih lastnosti, datagridview pa potem ustvarja nove nepotrebne kolone.

column pa vsebuje to:

i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

korenje3 ::

nevermind. sem že pogruntal...

        For Each dgvCol In c_columns
                .Columns.Add(dgvCol.DataPropertyName)
                .Columns(dgvCol.DataPropertyName).DataType = dgvCol.ValueType
                .Columns(dgvCol.DataPropertyName).ColumnName = dgvCol.Name
            Next


s tem da vsakič brišem datagridview1 tablo pred novim vnosom:

        With DataGridView1
            .DataSource = fxts.datasetu.Tables("users")
            .EnableHeadersVisualStyles = True
            .AlternatingRowsDefaultCellStyle.BackColor = Color.Azure
            .RowsDefaultCellStyle.BackColor = Color.AliceBlue
            .EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2
            .AllowUserToResizeRows = False
            .Columns.Clear()
        End With

        For Each column In fxts.c_columns
            DataGridView1.Columns.Add(column)
        Next
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

korenje3 ::

Imam še eno vprašanje.

recimo da programsko updejtam celice v datagridview. a obstaja opcija, da mi ne prekine ročnega vnosa novih podatkov (med tipkanjem v celico) v druge celice pri programskem vnašanju?
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

Zgodovina sprememb…

  • spremenil: korenje3 ()

cekr ::

DataGrid dela na osnovi baze in vsak Row je svoj record v bazi. Lahko to počneš.
Se moraš pa zavedat, da bo prej ali slej prišlo do zapisa v isto polje. Ti boš pisal, program ti bo pa hkrati popravljal vrednost. Ali pa recimo hkrati refreshanje celega rowa in ročnega pisanja. Takim situacijam se raje izogni. Tam, kjer je možnost, da bo v nekem času prišlo do refreshanja, raje zakleni možnost editiranja. Samo štalo boš imel s tem. Nikoli ne boš vedel pri, čem si.
Sinclair ZX Spectrum [Zilog Z80A - 3.5 MHz, 48kB, dvojni kasetofon,
TV-OUT, radirke, Sinclair-Basic], Sinclair ZX-81 [Z80A, 3.25MHZ, 1kB]

Looooooka ::

Ce te skrbi samo lokalno editiranje mas en zlo "cheap" nacin
v CellBeginEdit
das System.Threading.Monitor.Enter(tvojgridview.Rows[e.RowIndex].DataBoundItem);
potem das v CellEndEdit
System.Threading.Monitor.Exit(tvojgridview.Rows[e.RowIndex].DataBoundItem);

tam kjer probavas spremeniti podatke znotraj nekega drugega threada(timer...whatever) das pa lepo

lock(tvojgridview.Rows[tisti_row_ki_ga_spreminjas].DataBoundItem)
{
//update row...
}
oz With SyncLock(...) ce si v vb-ju.

oz System.Threading.Monitor.Enter(... in nato System.Threading.Monitor.Exit(... (lock in synclock delata tocno to).


Tako lahko background thread mirno spreminja rowe, ki jih ti ne editiras.
Ce background thread spreminja ravno tisti row, ki ga ti editiras bos opazil, da bo tvoj row deloval zaklenjeno.
Ce ga bos pa ti zacel editirati...ga bo tvoj background thread spremenil, ko bos ti koncal.

Druga alternativa je pa da iz backgroundthreada editiras podatke kar cez datagridview...in in pac klices vse metode za editiranje preko invoke metode. Ampak ne vidim nobenega pametnega razloga, da bi background thread klikal po kontrolah ce mu tega ni treba.


Aja ce bos pa kdaj zelel narediti lock na celi tabeli pa uporabljaj DataTable.Rows.SyncRoot property. Tega namrec uporablja tudi datatabela interno. Ce namesto datatabele uporabljas Listo...pa le to Castas v ICollection. Tam imas tudi SyncRoot property.
V glavnem na vseh objektih, kjer vidite da lahko direktno oz preko castanja pridete do SyncRoota...je to tisti property s katerim(pravilno napisane) komponente interno lockajo zadeve, ko jih spreminjajo :)

Aja...pa pri dolgo trajajajocih zadevah vcasih ni dobra ideja da kar klices lock oz synclock (recimo v timerju)...ker se lahko tako v queue nastavi ulala lockov. In ce request traja predolgo...ni glih fin efekt.
Takrat je mogoce pametno uporabiti Monitor.TryEnter(). Ce vrne false...exitas iz elapsed timer eventa in pac poskusis ob naslednjem klicu.

Zgodovina sprememb…

  • spremenilo: Looooooka ()

Looooooka ::

Ce bi recimo v zgornjemu primeru tist tvoj update iz threada trajal 10 sekund...in ti vmes probas editirat isti row...bi bil gui programa freeznen 10 sekund :). Ce das lepo tryenter v begin edit in ti ta vrne false das lepo e.Cancel na true in exitas iz procedure. Pac ne mores editirat v tistem momentu ampak vsaj gui ne bo freeznen.

korenje3 ::

thx. mi bo v veliko pomoč. sem že razmišljal da bi razdelil v dve datagridview tabeli... sam upam da ne bo potrebe.
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

korenje3 ::

Hm če uporabim synclock v timer threadu, mi dela same probleme. že samo da malo šarim po datagridview, mi zmeša rowe, ali pa meče errorje. če tega ne uporabim, dobivam pa error v datagridview: datatable internal index is corrupted '13'
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

Zgodovina sprememb…

  • spremenil: korenje3 ()

Looooooka ::

Kako spreminjas in kaj tocno spreminjas?
Problem je namrec sledec. DataTable ima tist svoj syncroot objekt.
Dataview ima spet svojo interno lockanje in pozicioniranje podatkov. In tam recimo ne moreta/smeta 2 razlicna threada kar tako spreminjati podatkov direktno. Ker ko se spremenijo podatki tisti filter ni updejtan in namesto da dataview dobi podatke, ki jih pricakuje...ugotovi, da podatkov ni vec oz so se spremenili. Mas takoj problem.
Potem synclock pomaga samo pri tem, da imas reseno to da 2 zadevi NE piseta naenkrat.
Ne resi pa tega, da thread poskusa spremeniti objekte, ki so bili ustvarjeni v drugem threadu(verjetno bos slej ko prej dobil se exception glede tega. Tako da moras v drugem threadu ponavadi klic narediti v kontekstu threada, ki je ustvaril tabelo...mas v spodnjem samplu kako se tak klic naredi)
V glavnem direktno spreminjanje podatkov iz drugega threada, ko uporabljas dataview, ki za datasource uporablja datatable je zajebana stvar.

Evo ti en cheap sample kako lahko dokaj varno updejas podatke, ko za dataview uporabljas navadno listo. Pa niti ta sample ni 100% full proof. Problem v samplu bo recimo tako, ko bos probal preko newrow eventa dodat nov objekt v grid...(lahko das allowusertoaddrows na true pa bos videl)

CheapTest.rar

Aja...pa glej tist debug output. Ti bo napisalo kdaj lahko spremenis prvo vrstico(ko thread ne pise po njej). Ima 5 sekundn delay not da ti da dovolj casa za spreminjaje. Ampak bi bla ista logika ce bi blo brez delaya :)

Naceloma bi pa priporocal, da cim prej upostevas cekr-jev nasvet.
Pri win formah datasetih in dataview-jih imas cisto prevec overheada, ko zelis vkljuciti neko multithreading logiko. Zguba casa, ki bi ga lahko porabil za kaj drugega :)

Zgodovina sprememb…

  • spremenilo: Looooooka ()

korenje3 ::

recimo..
selektriram celice randomly in vlečem čez celice poljubno. čez čas se mi kr celice zamenjajo...

Če hočeš ti lahko pošljem programček da sam vidiš...

najbolje bi bilo, če bi zadevo lahko rešil z System.timers.timer in ne z System.threading.timer
Problem je samo v tem, da recimo v system.timers.timer ne morem podati argumenta, recimo row s katerim bi operiral.
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

korenje3 ::

i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

korenje3 ::

ok ta reč je zdej zlo kompleksna. program mi zmrzne, če loadam podatke iz sql baze v tabelo v primeru da imam mtconnectorobj.ctimer.SynchronizingObject = Me
ne vem v čem je fora...

v primeru da ne loadam podatkov iz sql baze, dela vse normalno. ko loadam podatke se začne vse skupaj čudno vesti. ampak to šele po tem ko so podatki v tabelo oziroma lokalni dataset naloženi.

imam pa takole:

    Sub updatelist()
        If sqlcon.State = ConnectionState.Open Then
            Try
                adapter_users.Update(datasetu.Tables("users"))
            Catch ex As Exception
                MsgBox("exception updatelist: " & ex.ToString)
            End Try
        End If
    End Sub ' update mysql database
    Sub reloadlist()
        updatelist()
        If sqlcon.State = ConnectionState.Open Then
            datasetu.Tables("users").Clear()
            adapter_users.Fill(datasetu.Tables("users"))
        End If
        For Each row As DataRow In datasetu.Tables("users").Rows
            checktimer(row)
        Next
    End Sub ' update local database from mysql




i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

Zgodovina sprememb…

  • spremenil: korenje3 ()

Looooooka ::

za zacetek par nasvetov:
-vklopi strict (vidim, da imas funkcijo v smislu checktimer(byval row)...to sam prosis za napake, ki jih bos moral odkrivati kasneje
-vidim da si sel s timerjem per row in da ga potem nekje disposas...kjer se da uporabi rajsi using statement(ker ti bo disposal objekt tudi ce pride do exceptiona(ki pa seveda mora biti handlan)...s tem, da ne bos rabil pazi na to v 2-3 korakih kode.

za exception pa dejansko res zgleda kot threading error(z necem nekje spremenis podatke, in gridview o tem ni obvescen...in potem dobis tist error 13 thingy.
Zdaj lahko samo ugibam kje(na posnetku se zal ne vidi dovolj dobro kode) ampak...glede na to, da si napisal, da pride do napake ko loadas podatke gledam tale del kode:(datasetu.Tables("users").Clear()...)
ce se tole izvaja med tem, ko so podatki ze nalozeni in ze klikas po gridviewju zna mogoce priti do problema

datasetu.Tables("users").Clear()
adapter_users.Fill(datasetu.Tables("users"))

mogoce bi pomagalo ce bi dal prej:

GridView.DataSource = null
GridView.SuspendLayout()
datasetu.Tables("users").Clear()
'ce so se ob tem spremenili tudi columni das se
GridView.Columns.Clear();

adapter_users.Fill(datasetu.Tables("users"))
potem spet dodas columne...
'foreach blabla ce nimas autogeneratecolumns...

GridView.DataSource =datasetu.Tables("users")
GridView.ResumeLayout(true)

Zal kaj vec tezko recem, ker komaj vidim kodo na posnetku plus winformsov in datagridviewja nisem uporabljal ze leta.
Ampak hvala za grozljiv spomin na preteklost. Kot je bilo ze omenjeno...v WPF-ju so te zadeve tako ultra elegantne, da se clovek res lahko posveti sami logiki in izgledu programa in ne zapravi polovice casa za drobovje in lovljenje pravega vrstnega reda eventov :)

Sumim, da je kriv timing izvajanja metode reloadlist. Poskusi nekaj v smislu zgoraj napisanega. Disconectat source iz gridaview preden ga spucas nalozis ponovno in ga sele potem prikljuci nazaj na gridview. Ponavadi mu ni vsec, da med samim delovanjem (ko ze klikamo po njemu...nekdo spuca celo tabelo s podatki...oz zbrise row, ki ga je ravno interno sfiltriral).

Zgodovina sprememb…

  • spremenilo: Looooooka ()

korenje3 ::

preden ustvarim datagridview imam takole:

   Public Sub resetdatagridview()
        With DataGridView1
            .DataSource = fxts.datasetu.Tables("users")
            .EnableHeadersVisualStyles = True
            .AlternatingRowsDefaultCellStyle.BackColor = System.Drawing.Color.Azure
            .RowsDefaultCellStyle.BackColor = System.Drawing.Color.AliceBlue
            .EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2
            .AllowUserToResizeRows = False
            .Columns.Clear() ' zbriše kolone, ohrani podatke v tabeli!
            .DefaultCellStyle.NullValue = .DefaultCellStyle.NullValue
        End With
        For Each c As DataGridViewColumn In fxts.c_columns
            If c.ValueType IsNot GetType(Guid) Then
                DataGridView1.Columns.Add(c)
            End If
        Next


Potem pa še vsak column konfiguriram posebej...

        With fxts.c_ID
            .ToolTipText = "User name"
            .DisplayIndex = 1
            .ValueType = fxts.c_ID.ValueType
        End With


zdej načeloma ne vem... a bi se mogu tale column pokazat v datagridview, glede na to da sem prej ustvaril tabelo in potem naložil podatke iz dataset.table?

 .Columns(d_mtserver.ColumnName).DefaultValue = New mtconnector
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

Zgodovina sprememb…

  • spremenil: korenje3 ()

korenje3 ::

že vidm v čem je fora. verjetno bom moral kr odstranit ta reload opcijo, ker se ob vsakem clear table zbrišejo rowi, ki se potem ne zapišejo z istim uid ko prebere iz sql baze. potem mam pa timerje ki niso nikamor vezani...

a obstaja mogoče opcija, da mi sql updejta rowe v datasetu, v primeru da so spremenjeni, ali pa da jih ni?
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

Looooooka ::

a ni v videposnetku tko da pri reloadu ti spraznis tabelo v datasetu in jo pol reloadas?
kje je problem?
ko updejtas tiste "uid"-je pred reloadom morajo seveda bit zapisani.

kaj tocno je ta uid, kdaj ga nastavis, zakaj ga ne zapises v bazo, ko ga spremenis in preden delas reload?

korenje3 ::

a nima vsak row svoj interni id? to sem mislil. recimo če 2x reloadam iz sql baze, se mi zapisi podvajajo v tabeli, zato sem imel clear table. karkoli že baje ni možno imeti datagridview in thrading skupaj: http://stackoverflow.com/questions/6744...

misliš da bi bilo bolje, če bi ustvaril nov class z začasnimi podatki, katere bi z threadi spreminjal? potem bi pa v osnovnem threadu spreminjal tabele? al je nov table pa nov class eno in isto?

karkoli že, torej če pri vsakem reloadu iz mysql naredi rowe z drugimi identi, pomeni da so vsi timerji vezani na stare rowe. in ko dam clear table, postanejo tisti timerji "dangling" al kako bi reku.

i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

Zgodovina sprememb…

  • spremenil: korenje3 ()

Looooooka ::

Am datagridview nima nobenega internega id-ja
v dataset se nalozijo tabele..te majo svoj index 0,1,2,3 in seveda lahko jih klices tudi preko imena dataset("nekoimetabele")
te tabele prav tako nimajo internega id-ja za rowe ampak imajo spet index. table.rows(0) 1, 2, 3 ,4....
vrstni red je odvisen od queryja, ki se ga uporabi v select statementu.
ce dataset naredis preko winforms wizarda(direktno na gridviewju recimo) ti ta naredi bindingsource tableadapter the works...in obenem tudi typed dataset, ki ze exposa tabele kot propertyje.

tako ima tak dataset v katerega si recimo dodat Tabela1 in Tabela2 preko wizarda ze propertyja z istim imenom.
In preko tega propertyja lahko tudi klices metodo FindByID, ki ti vrne rowview glede na primary key v tabeli.
ce ti ta dataset filas sam z lastnimi queryji potem lahko do tabel(tako kot v tvojem video posnetku) dostopas lepo preko
Dataset("imetabele")
to ti vrne instanco, ki je tipa DataTable.
In DataTable ti exposa funkcijo z imenom "select"
preko nje lahko vedno najdes rowview s filtriranjem.
Recimo da ima tabela Test 2 kolumna. ID in Name (id je navaden int Name pa recimo nvarchar ali text)
Dim rows() As DataRow = DataSet["Test"] .Select("ID=6") //vrne array, ki vsebuje en element(row) z id-jem 6
rows = DataSet["Test"] .Select("Name LIKE '%test%'") //vrne array z rowi, kjer column "Name" vsebuje besedo test

Ampak pozor...tista tvoja logika, kjer vsakemu rowu dodas nek objekt, ki potem updejta ta row ne bo delovala.
mislim, da si v videoposnetku rowu dodal objekt...potem spucal rowe...jih nalozil...timer pa je potem uporabil tabelo iz dataseta in po njej iskal tisti row.
ce ze cutis neko silno potrebo, da za vsak row laufas svoj objekt/timer potem mora biti to definitivno v neki svoji listi.
in kot parameter po katerem bo shranil referenco na row NE SME biti NE row niti INDEX iz tabele, ki je v datasetu.
Edino kar pride v postev je primary key iz tabele(v zgorjem primeru bi bil to column "ID").
Row potem vsakic poisces kot je napisano zgoraj.
AMPAK!!!!!!!!!
Se zmeraj imas problem.
In sicer....ti bos naredil ene 20 takih timerjev oz objektov(karkoli ze so). ti objekti bodo po neki logiki(timer, event,whatever...ne vem) ob nekem random casu probali poiskati ta row in spremeniti neko vrednost.
Ce bos ti med tem spucal dataset oz tabelo v datasetu...timer rowa ne bo nasel. Torej bos moral poskrbeti, da imas to (clear/reload) logiko spet sinhronizirano z logiko v teh timerjih/objektih (magar synclock...) tako, da noben izmed teh timerjev/objektov, ne bo poskusal iskati IN spreminjati rowa, dokler se izvaja clear/load.
Prav tako se clear/load, ne sme izvajati, ko ti timerji spreminjajo podatke.

Zgodovina sprememb…

  • spremenilo: Looooooka ()

Looooooka ::

Pa preden se v tole zapicis...eno vprasanje.
Zakaj sploh reloadas bazo?
Jo spreminja nekdo drug od zunaj?
Ker ce vse spremembe v teh tabelah delas znotraj te aplikacije...sploh ni nobene potrebe, da bi dataset/tabele kadarkoli reloadal(ce seveda vsakiz nalozis VSE podatke)...ce jih nalagas glede na neke filtre pa se vedno pride v postev zgornja "logika".

Zgodovina sprememb…

  • spremenilo: Looooooka ()

Looooooka ::

Oh se opravicujem za tiste [] oklepaje ( DataSet["Test"] )...pisem na pamet in ker sam ponavadi pisem v c#-ju vcasih pozabim, da je treba v vb-ju uporabljati okrogle oklepaje :D

korenje3 ::

tisto reloadanje baze je blilo zato, ker sem mislil da bo mysql samo dodal nove rowe v primeru da manjkajo v dataset.datatable.
Pa sem potem ugotovil da doda vse rowe... mislim da sem razmišljal tudi o opciji "cancel changes" ipd...

predvidevam da bom dodal column z guid za primarykey (c_hash.datapropertyname).
pa tole: Dim rows() As DataRow = DataSet["Test"] .Select("ID=6")
a ni to potem rows() datarowcollection ?

bom probal sedaj narediti posebno "začasno" tabelo v katero se bodo dodajali rowi v primeru da active=1.
ko bo active=1 se bo dodal row v drugo tabelo kamor bom dodal objekt timerja. v tej tabeli bo svoj lasten row spreminjal samo thread (predvidevam da se row ne spremeni, če zbrišem kakšen drugi row??). ko si rekel da so rowi oštevilčeni, se row izgubi za thread, če zbrišem row z višjo številko in/ali nižjo številko?

torej bom imel 2 identična guida v obeh tabelah... upam da sem na pravi poti. edini problem bo hitrost, ker bo treba najti row z guidom v drugi tabeli za vsako malenkost.
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

Zgodovina sprememb…

  • spremenil: korenje3 ()

Looooooka ::

Recimo da si tabelo zafilal z 10imi rowi.
in potem tabelo uporabil v dataviewju.
na zacetku bores rowview(0) kazal na row(0) v datatabeli.
ampak ce bi v dataviewju uporabil filter...order by potem to vec ne drzi. ker lahko dataview zaradi filtra mogoce prikazuje samo 5 rowov.Pa se teh 5 je mogoce zadnjih 5 v datatabeli.
Iso velja za rowe iz datagrida. To je interni index komponente. POGLED na podatke iz datatabele in se ga zato NE sme NIKOLI uporabljati za referenco, ki se uporabljala za iskanje podatkov, ko/ce bodo ti spremenjeni/nalozeni na novo ali v drugacnem vrstnem redu.
Vedno se sklicuj na fixen podatek iz same baze. Po moznosti nek unique key(v bazi se ponavadi primary keye naredi unique in so zato primerni za tako referenco).
Nacin kam in kako jih spravis ni pomemben. Vazno, da ves kje se podatek trenutno nahaja in ga lahko ko ga rabis poisces in spremenis.

korenje3 ::

a lahko še enkrat...
zdej praktično vse kar se dela v threadu se shranjuje v class. to dela brez problemov in če updejtam datatable izven threadov (tako da preberem classe vsakega threada) dela v redu. edini problem je pač hitrost ker mora narest zadevo št.rowov^2.

torej če dam v threadu tole:

    Private Sub timer_mtconnect()
        mtconnecting = True
        'MsgBox("timer: " & connect.UID.ToString)
        If m_mtclient.IsConnected <> True Then
            Try
                m_mtclient.Connect(m_Address, m_Port)
                m_row.BeginEdit()
                m_row.ClearErrors()
                m_row.AcceptChanges()
                m_row.EndEdit()
                timer_stop()
            Catch ex As Exception
                m_failcount += 1
                m_row.BeginEdit()
                m_row.RowError = "Error connecting"
                m_row.Item(fxts.c_Regime3.DataPropertyName) = "F: " & m_failcount
                m_row.Item(fxts.c_Regime2.DataPropertyName) = "S: " & m_Address
                m_row.AcceptChanges()
                m_row.EndEdit()
            End Try
        End If
        mtconnecting = False
    End Sub


mi zadeva še vedno ne funkcionira. sem probal z synclock fxts.users (datatable) pa synclock m_row.table pa synclock m_row
v glavnem nič ne dela da nebi ven vrglo errorja. če naredim ene 50 threadov mi samo od sebe vrže ven da rowa ne najde ali pa da se je primarykey podvojil.
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

korenje3 ::

hm. Sem dal snyclock izven try in zgleda da dela. Cel program se mi sicer zatika, sam dela. Nisem si mislu da bo 70 threadov toliko kurilo procesor.
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

korenje3 ::

ah ok sm že pogruntu.

        For Each connect As mtconnector In usersconn
            connect.row(c_Regime3.DataPropertyName) = "F: " & connect.failcount
            connect.row(c_Regime2.DataPropertyName) = "S: " & connect.Address
        Next


Tole dela dokaj hitro. Samo še timerji pokurijo veliko proca. verjetn je kriv threadpooling.
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

korenje3 ::

izgleda da debugging pokur ves cpu. običajno mi kuri max 1% cpuja pri cca 50 threadih. timerje sem vrgu ven. V glavnem zdej dela vse kot mora, predvsem pa hitro.

i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

Zgodovina sprememb…

  • spremenil: korenje3 ()


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[VB] polepšanje kode

Oddelek: Programiranje
7684 (590) korenje3
»

vb mysql dataset update

Oddelek: Programiranje
81139 (1019) korenje3
»

DataView, DataTable, DataSet

Oddelek: Programiranje
91086 (837) detroit
»

c# datagridview in combox

Oddelek: Programiranje
131135 (1023) OmegaM
»

[C#] DATA GRID VIEW

Oddelek: Programiranje
131849 (1729) Kekec

Več podobnih tem