[C#]DataGridView/BindingSource en filteren met lege waardes

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • MewBie
  • Registratie: April 2002
  • Laatst online: 23:48
In mijn vorige topic had ik wat problemen met het vervangen van een bepaald karakter in een excel waarde, inmiddels is mijn programma al wat verder en kan ik leuk heen en weer gooien met data tussen mijn programma en een aantal databases. Nu loop ik echter tegen een probleem aan met het filteren van deze data.

De data die ik uit de database haal wordt in een dataset met een aantal tables geplaatst, 1 van deze tables wordt d.m.v. een BindingSource weergegeven in een DataGridView.
Vervolgens wordt er aan de hand van 3 kolommen een TreeView gevuld, deze TreeView gebruik ik voor het filteren van de data die de DataGridView weer geeft en heeft 4 lagen.

De eerste laag bestaat uit 1 node en bij selectie van deze node wordt de BindingSource.Filter op Null gezet.
Het filteren d.m.v. selectie in de treeView gaat goed totdat er lege velden bij komen kijken.
Tijdens het vullen van de TreeView worden eventuele lege velden vervangen door de waarde "Unknown" in de TreeView, dit omdat "" nogal lastig te selecteren is in een TreeView :+
Tijdens het aanroepen van de filter code vervang ik de waarde "Unknown" weer voor "" en tot zover gaat alles goed, alle "Unknown" waardes in elke laag van de TreeView wordt netjes vervangen door "".

Het filter zelf levert echter wat problemen op...
Als ik laag1 selecteer wordt netjes alle data weergegeven (BindingSource.Filter = null)
Als ik laag2 selecteer wordt netjes de gefilterde data weergegeven.
Als ik laag 3 of 4 selecteer gebeurd er wat vreemd, zodra 1 van deze 2 de waarde "Unknown" in de TreeView heeft en in de DataGridView dus "" worden er geen resultaten meer weergegeven. Hebben laag 3 en/of 4 een andere waarde als "Unknown" dat werkt het filter naar behoren.

code:
1
2
3
4
5
6
7
8
BindingSource.Filter = "Laag2 = '_waarde1' "
Deze werkt naar behoren, ongeachte de wat er in _waarde1 staat.

BindingSource.Filter = "Laag2= '_waarde1' AND Laag3 = '_waarde2' "
Deze werkt ook zolang _waarde2 geen "" is.

BindingSource.Filter = "Laag2 = '_waarde1' AND Laag3 = '_waarde2' AND Laag4 = '_waarde3' "
Deze werkt ook zolang _waarde2 en/of _waarde3 geen "" is.

Wat is de reden dat het filter niet werkt zodra Laag3 of Laag4 "" is?

De waarde van BindingSource.Filter is gewoon wat het zijn moet, bijvoorbeeld
"Laag2 = '' AND Laag3 = '' AND Laag4 = ''"
als ik de node selecteer die overal al waarde "Unknown" heeft

Please leave a message after the beep.
*beeeeep*


Acties:
  • 0 Henk 'm!

  • P-Storm
  • Registratie: September 2006
  • Laatst online: 23:32
"Laag2 = '' AND Laag3 = '' AND Laag4 = ''"
moet dat niet iets van
"Laag2 = "'' AND Laag3 = "'' AND Laag4 = ''""
worden?

Ik heb het gevoel als je in laag 1 "" voert dat de andere filters dan nog niet eens gebruikt worden, maar goed dit is een gut feeling.

Acties:
  • 0 Henk 'm!

  • MewBie
  • Registratie: April 2002
  • Laatst online: 23:48
De '' na het = teken zijn 2 enkele aanhalingstekens ;)

Please leave a message after the beep.
*beeeeep*


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Bedoel je niet IS NULL ipv ="" ? ;)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • MewBie
  • Registratie: April 2002
  • Laatst online: 23:48
Goed, even wat meer code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
string path = TreeView1.SelectedNode.FullPath;
            string[] pathNodes = null;
            int i = 0;

            pathNodes = path.Split('\\');

            foreach(string s in pathNodes)
            {
                if(s == "Unknown")
                {
                    pathNodes[i] = "";
                }
                i++;
            }

            switch(pathNodes.Length)
            {
                case 1:
                    BindingSource.Filter = null;
                    break;
                case 2:
                    BindingSource.Filter = "Laag2 = '" + pathNodes[1] + "'";
                    break;
                case 3:
                    BindingSource.Filter = "Laag2 = '" + pathNodes[1] + "' AND Laag3 = '" + pathNodes[2] + "'";
                    break;
                case 4:
                    BindingSource.Filter = "Laag2 = '" + pathNodes[1] + "' AND Laag3 = '" + pathNodes[2] + "' AND Laag4 = '" + pathNodes[3] + "'";
                    break;
                default:
                    BindingSource.Filter = null;
                    break;

            }

Deze code wordt uitgevoerd in de AfterSelect van de TreeView en bepaald welke node ik geselecteerd heb, knipt het path van de node in stukken en bepaald welk filter gebruikt wordt.
Of ik "Unknown" nu door "" of door null vervang maakt niks uit.

Please leave a message after the beep.
*beeeeep*


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Dit ziet er nogal lelijk uit vanwege een mogelijk gebrek aan normalisatie (Laag[1-4]), gebrek aan escaping (O'J), en de repeterende code/onhandige foreach. Ik denk dat je met wat linq die hele functie zelfs in een paar regels kan krijgen (incl. escaping en 'is null' generatie).

Verder is =null of ='' iets anders dan is null. Stel anders eens handmatig een filter in, en kijk of dat wel werkt. ;)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • MewBie
  • Registratie: April 2002
  • Laatst online: 23:48
Ik ben geen programmeur van beroep, nette code is dus geen vereiste zolang het maar werkt. :+

BindingSource.Filter = "Laag2 = Null AND Laag3 = Null";
en
BindingSource.Filter = "Laag2 Is Null AND Laag3 Is Null";
werken beiden ook niet.

Please leave a message after the beep.
*beeeeep*


Acties:
  • 0 Henk 'm!

  • ArtyShock
  • Registratie: Juli 2002
  • Laatst online: 05-09 13:45
Misschien simpel gedacht hoor, maar als je niet op Laag2 wilt filteren, waarom dit dan toch in de filter-expression opnemen met constructies als Laag2 = '' of Laag2 IS NULL? Neem alleen die columns in je filter op die je ook werkelijk wilt filteren.

Acties:
  • 0 Henk 'm!

  • epic007
  • Registratie: Februari 2004
  • Laatst online: 25-08 11:27
MewBie schreef op maandag 13 augustus 2012 @ 14:27:
Ik ben geen programmeur van beroep, nette code is dus geen vereiste zolang het maar werkt. :+
Mijn ervaring is dat werkende code ook vaak nette code is.

Acties:
  • 0 Henk 'm!

  • MewBie
  • Registratie: April 2002
  • Laatst online: 23:48
ArtyShock schreef op dinsdag 14 augustus 2012 @ 13:35:
Misschien simpel gedacht hoor, maar als je niet op Laag2 wilt filteren, waarom dit dan toch in de filter-expression opnemen met constructies als Laag2 = '' of Laag2 IS NULL? Neem alleen die columns in je filter op die je ook werkelijk wilt filteren.
Ik wil juist de resultaten zien waarbij de waardes in bepaalde kolommen leeg zijn. ;)
Delen van het filter weg laten gaat hele rare resulaten geven. :+

Even wat ascii art:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
+Laag1
|+Laag2
||+Laag3
|||-Laag4
|||-Laag4
||+Laag3
| |-Laag4
| |-Laag4
|+Laag2
||+Laag3
| |-Laag4
||+Laag3
| |-Laag4
|-Laag2

Hopelijk is het duidelijk, maar als Laag2 dus de waarde '' heeft kan ik die niet weglaten omdat ik dan Laag3 en/of 4 laat zien bij alle waardes van Laag2.

En mijn filters werken zoals de bedoeling is, behalve als Laag3 en/of Laag4 de waarde '' heeft.

[ Voor 5% gewijzigd door MewBie op 14-08-2012 14:56 ]

Please leave a message after the beep.
*beeeeep*


Acties:
  • 0 Henk 'm!

  • epic007
  • Registratie: Februari 2004
  • Laatst online: 25-08 11:27
Hier staat wel iets over een ISNULL expressie.

Maar misschien moet je je filter string in de foreach lus opbouwen:

C#:
1
2
3
4
5
6
7
8
string filterString = "";
foreach(string s in pathNodes)
{
    if(s != "Unknown")
        filterString += "......."
}

BindingSource.Filter = filterString;


Als er twee keer een lege (Unknown) in je tree voorkomt moeten die dan niet worden samengevoegd?

Van dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
+Laag1
|+Laag2
||+Laag3
|||-Laag4
|||-Laag4
||+Laag3
| |-Laag4
| |-Laag4
|+Laag2
||+Unknown  <---
| |-Laag4-1
||+Unknown  <---
| |-Laag4-2
|-Laag2


Naar dit?
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
+Laag1
|+Laag2
||+Laag3
|||-Laag4
|||-Laag4
||+Laag3
| |-Laag4
| |-Laag4
|+Laag2
||+Unknown  <---
| |-Laag4-1
| |-Laag4-2
|-Laag2

[ Voor 37% gewijzigd door epic007 op 15-08-2012 11:17 ]


Acties:
  • 0 Henk 'm!

  • MewBie
  • Registratie: April 2002
  • Laatst online: 23:48
epic007 schreef op woensdag 15 augustus 2012 @ 11:13:
Hier staat wel iets over een ISNULL expressie.

Maar misschien moet je je filter string in de foreach lus opbouwen:

C#:
1
2
3
4
5
6
7
8
string filterString = "";
foreach(string s in pathNodes)
{
    if(s != "Unknown")
        filterString += "......."
}

BindingSource.Filter = filterString;
Zoiets zou ik nog kunnen proberen, heb vandaag alleen andere prioriteiten en dus geen tijd om te programmeren.
Als er twee keer een lege (Unknown) in je tree voorkomt moeten die dan niet worden samengevoegd?

Van dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
+Laag1
|+Laag2
||+Laag3
|||-Laag4
|||-Laag4
||+Laag3
| |-Laag4
| |-Laag4
|+Laag2
||+Unknown  <---
| |-Laag4-1
||+Unknown  <---
| |-Laag4-2
|-Laag2


Naar dit?
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
+Laag1
|+Laag2
||+Laag3
|||-Laag4
|||-Laag4
||+Laag3
| |-Laag4
| |-Laag4
|+Laag2
||+Unknown  <---
| |-Laag4-1
| |-Laag4-2
|-Laag2
Dat gebeurd al, alles wordt netjes gegroepeerd.
Het probleem zit hem echt alleen maar in het filter als Laag3 en/of Laag4 de waarde "Unknown" hebben in dus treeview en de "" in de datatable/datagridview.

Als ik tijd heb zal ik eens kijken of ik e.e.a. om kan zetten naar een losstaand programmaatje met hetzelfde probleem.

Please leave a message after the beep.
*beeeeep*

Pagina: 1