Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.

[NET 2.0] delete op datagridview probleem

Pagina: 1
Acties:

  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 06:40
Ik heb een hele reeks met POCO's (Plain Old CLR objects), of eigenlijk business entities. Het zijn slechts placeholders van data, meer niet. Deze leidt af van een base entity waar 3 properties op zitten: IsDeleted, HasChanged, IsNew.

Ik heb een scherm gemaakt met bovenaan enkele textboxes en daaronder een datagridview. Deze is via het bindingmechanisme aan elkaar gekoppeld. De entities zijn opgeslagen in een List<T>, deze is dus gekoppeld aan de grid en textboxes.

Als ik een rij verwijder, zet ik de IsDeleted op TRUE en doe ik een actieve filtering op de List<T> middels een Predicate<T> aka

code:
1
2
3
4
this.productList = this.productList.FindAll(delegate(Product product)
{
  return product.IsDeleted = false;
})


En daarna bind ik 'm opnieuw en het werkt goed: de grid wordt netjes gefiltered zodat de verwijderde entity uit de lijst verdwijnt. Echter.... nu het probleem:

Ik wil op de OK click van de form de List<T> wegschrijven naar een file. Nu wil ik itereren door de List<T> en afhankelijk van de 3 bovengenoemde properties verschillende CRUD operaties op de file uitvoeren. Alleen het probleem is nu dat door de gefilterde List<T> mijn entity echt verdwenen is (want ik vervang de List<T> door de nieuw gefilterede variant).

Nu zit ik te dubben hoe ik dit op een simpele, elegante wijze kan oplossen... hebben jullie ideeën?

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Door productList misschien *niet* te overschrijven?
C#:
1
2
3
4
5
6
List<Product> visibleProducts = this.productList.FindAll(delegate(Product product)
{
  return product.IsDeleted = false;
})

grid.DataSource = visibleProducts;

Je originele productList bevat dan nog steeds alle entities en kun je gewoon je CRUD operaties uitvoeren.

If it isn't broken, fix it until it is..


  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

Verwijder je het object ook uit je List<T> of markeer je hem alleen maar via het IsDeleted property?
In het 2e geval is de oplossing relatief eenvoudig en dat is gebruik maken van twee List<T>'s.
Voorbeeldje:
C#:
1
2
3
4
5
6
7
private void ApplyFilter() {
    List<T> filteredList = _fullList.FindAll(delegate(Product product) {
        return !product.IsDeleted;
    }

    // Bind filteredList aan DataGridView
}

Na deleten kun je door de totale list lopen en daar het IsDeleted property uitvragen.

edit:
Sneller submitten de volgende keer

[ Voor 4% gewijzigd door MTWZZ op 28-08-2008 09:35 ]

Nu met Land Rover Series 3 en Defender 90


  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 06:40
Niemand_Anders schreef op donderdag 28 augustus 2008 @ 09:26:
Door productList misschien *niet* te overschrijven?
C#:
1
2
3
4
5
6
List<Product> visibleProducts = this.productList.FindAll(delegate(Product product)
{
  return product.IsDeleted = false;
})

grid.DataSource = visibleProducts;

Je originele productList bevat dan nog steeds alle entities en kun je gewoon je CRUD operaties uitvoeren.
2 lijstjes was ook mijn gedachte, maar is wel veel extra handling.Ik moet het origineel namelijk dan ook in sync houden met de gewijzigde data (new & edit)

[ Voor 7% gewijzigd door DrDelete op 28-08-2008 10:16 ]


  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 06:40
MTWZZ schreef op donderdag 28 augustus 2008 @ 09:34:
Verwijder je het object ook uit je List<T> of markeer je hem alleen maar via het IsDeleted property?
In het 2e geval is de oplossing relatief eenvoudig en dat is gebruik maken van twee List<T>'s.
Voorbeeldje:
C#:
1
2
3
4
5
6
7
private void ApplyFilter() {
    List<T> filteredList = _fullList.FindAll(delegate(Product product) {
        return !product.IsDeleted;
    }

    // Bind filteredList aan DataGridView
}

Na deleten kun je door de totale list lopen en daar het IsDeleted property uitvragen.

edit:
Sneller submitten de volgende keer
Het is de 2e optie, slechts markeren. Echter... met jouw oplossing ben ik de variabele filtered list kwijt vanwege de variabele binnen de private void.

  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

DrDelete schreef op donderdag 28 augustus 2008 @ 10:11:
[...]


Het is de 2e optie, slechts markeren. Echter... met jouw oplossing ben ik de variabele filtered list kwijt vanwege de variabele binnen de private void.
Was slechts als voorbeeld bedoeld. filteredList hoort in je class.

Nu met Land Rover Series 3 en Defender 90


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

DrDelete schreef op donderdag 28 augustus 2008 @ 10:07:
[...]


2 lijstjes was ook mijn gedachte, maar is wel veel extra handling.Ik moet het origineel namelijk dan ook in sync houden met de gewijzigde data (new & edit)
Nee, je houd alleen het origneel in sync. Een Product in de gefilterde lijst heeft gewoon dezelfde reference (althans mij aanname is dat Product een class en geen struct is) als in de originele lijst. Ofwel als je IsDeleted op true zet voor een Product uit de gefilterde lijst zal deze ook op verwijderd staan in je ProductList.

Je hebt dus niet echt twee lijstjes. Je kunt visibleProducts meer zien als een 'view' van productList.

Bij het webschrijven doorloop je dan ook productList.

If it isn't broken, fix it until it is..


  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 06:40
Niemand_Anders schreef op donderdag 28 augustus 2008 @ 11:25:
[...]

Nee, je houd alleen het origneel in sync. Een Product in de gefilterde lijst heeft gewoon dezelfde reference (althans mij aanname is dat Product een class en geen struct is) als in de originele lijst. Ofwel als je IsDeleted op true zet voor een Product uit de gefilterde lijst zal deze ook op verwijderd staan in je ProductList.

Je hebt dus niet echt twee lijstjes. Je kunt visibleProducts meer zien als een 'view' van productList.

Bij het webschrijven doorloop je dan ook productList.
dat klopt niet: de gefilterde lijst heeft de entities niet meer waar de IsDeleted op TRUE is gezet, die zijn namelijk door de filtering weg en dat is nou juist het grote probleem.

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
DrDelete schreef op donderdag 28 augustus 2008 @ 11:47:
[...]


dat klopt niet: de gefilterde lijst heeft de entities niet meer waar de IsDeleted op TRUE is gezet, die zijn namelijk door de filtering weg en dat is nou juist het grote probleem.
Ja maar als je dan een record wilt deleten pak je gewoon dat item uit de gefilterde list en zet je zijn property IsDeleted op true, en dan filter je de lijst opnieuw.

Dan hoef je toch niet meer dingen te syncen. Bij het toevoegen van een item voeg je hem gewoon toe aan je complete lijst en filter je die opnieuw.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • MTWZZ
  • Registratie: Mei 2000
  • Laatst online: 13-08-2021

MTWZZ

One life, live it!

DrDelete schreef op donderdag 28 augustus 2008 @ 11:47:
[...]


dat klopt niet: de gefilterde lijst heeft de entities niet meer waar de IsDeleted op TRUE is gezet, die zijn namelijk door de filtering weg en dat is nou juist het grote probleem.
Wat Niemand_Anders zegt klopt wel hoor.
quick n dirty:
C#:
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
public partial class Form1 : Form
{
    private List<Product> productList;
    private List<Product> filteredList;

    public Form1()
    {
        InitializeComponent();

        productList = new List<Product>();

        for (int i = 0; i < 20; i++)
        {
            productList.Add(new Product(i));
        }

        Filter();
    }

    private void Filter()
    {
        filteredList = productList.FindAll(
            delegate(Product p)
            {
                return !p.IsDeleted;
            }
        );

        dataGridView1.DataSource = filteredList;
    }

    private void buttonDelete_Click(object sender, EventArgs e)
    {
        if (dataGridView1.SelectedRows == null || dataGridView1.SelectedRows.Count < 1)
        {
            return;
        }

        Product p = (Product)dataGridView1.SelectedRows[0].DataBoundItem;

        p.IsDeleted = true;

        Filter();
    }

    private void buttonSave_Click(object sender, EventArgs e)
    {
        foreach (Product p in productList)
        {
            if (p.IsDeleted)
            {
                MessageBox.Show("item with index " + p.Index + " is deleted!");
            }
        }
    }
}
Maar nu wijzig je data... dat gebeurt dus op de gefilterde list, want de textbox is gebind aan de gefilterde list.
Nee want de geselecteerde instance van Product in filteredList is nog steeds een referentie naar dezelfde instance van Product in productList
Bij een delete verdwijnt de entity omdat het resultaat van de FindAll het origineel vervangt en daarmee dus ook de als IsDeleted gemarkeerde entity.
FindAll geeft het resultaat in filteredList. Zolang jij er voor zorgt dat dat zo is dan zal een instance waar IsDeleted op true staat altijd in de productList blijven totdat je die ook uit productList verwijderd.

[ Voor 78% gewijzigd door MTWZZ op 28-08-2008 12:06 ]

Nu met Land Rover Series 3 en Defender 90


  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 06:40
rwb schreef op donderdag 28 augustus 2008 @ 11:51:
[...]

Ja maar als je dan een record wilt deleten pak je gewoon dat item uit de gefilterde list en zet je zijn property IsDeleted op true, en dan filter je de lijst opnieuw.

Dan hoef je toch niet meer dingen te syncen. Bij het toevoegen van een item voeg je hem gewoon toe aan je complete lijst en filter je die opnieuw.
bij de filtering verdwijnt de item uit de list omdat je de list instance vervangt door het resultaat van de FindAll

Bij toevoegen is het geen probleem, dan is het inderdaad: toevoegen en opnieuw filteren. Maar nu wijzig je data... dat gebeurt dus op de gefilterde list, want de textbox is gebind aan de gefilterde list.

Het probleem is echter alleen op de delete. De edit & new gaan goed. Bij een delete verdwijnt de entity omdat het resultaat van de FindAll het origineel vervangt en daarmee dus ook de als IsDeleted gemarkeerde entity.

[ Voor 12% gewijzigd door DrDelete op 28-08-2008 12:03 ]


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
DrDelete schreef op donderdag 28 augustus 2008 @ 12:02:
[...]
Het probleem is echter alleen op de delete. De edit & new gaan goed. Bij een delete verdwijnt de entity omdat het resultaat van de FindAll het origineel vervangt en daarmee dus ook de als IsDeleted gemarkeerde entity.
Maar als je een comleteList en een filteredList hebt dan heb je dat probleem niet.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 06:40
rwb schreef op donderdag 28 augustus 2008 @ 12:13:
[...]

Maar als je een comleteList en een filteredList hebt dan heb je dat probleem niet.
dat is lastig met de edits,,,

ik heb het nu anders opgelost.

Ik heb een deletedlist aangemaakt. Bij verwijdering markeer ik zoals voorheen, echter de entity voeg ik toe aan de deletedlist. Bij de Save biedt ik beide lijsten aan: de gefilterede (waar de entity nu weg is) en de deletedList waar alleen de verwijderde entities aanwezig zijn en het werkt!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
DrDelete schreef op donderdag 28 augustus 2008 @ 12:15:
[...]
dat is lastig met de edits,,,
Waarom zou dat lastig zijn met edits...?

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • DrDelete
  • Registratie: Oktober 2000
  • Laatst online: 06:40
rwb schreef op donderdag 28 augustus 2008 @ 12:16:
[...]

Waarom zou dat lastig zijn met edits...?
edits werken op de gefilterde list, bij de save moet ik de gefilterde data in sync brengen met het orgineel

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
DrDelete schreef op donderdag 28 augustus 2008 @ 12:22:
[...]
edits werken op de gefilterde list, bij de save moet ik de gefilterde data in sync brengen met het orgineel
De edits die je in de gefilterde list maakt die zie je ook in de ongefilterde list.

C#:
1
2
3
4
5
6
7
List<MyObject> list1 = new List<MyObject>();
list1.Add( new MyObject( "list1" ) );
List<MyObject> list2 = list1.FindAll( delegate { return true; } );

list2[0].Property = "list2";

Messagebox.Show( list1[0].Property );

zal tenslotte ook "list2" displayen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1