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

[c# winforms]Probleem met Datagrid

Pagina: 1
Acties:

  • raptorix
  • Registratie: Februari 2000
  • Laatst online: 17-02-2022
Als volgt, ik heb een datagrid die gevult wordt met een XML file, op volgende manier:

code:
1
2
3
4
5
6
7
8
        private void Load_Xml()
        {
            XmlDataDocument xmlDatadoc = new XmlDataDocument();
            xmlDatadoc.DataSet.ReadXml("nations.xml");
            ds = xmlDatadoc.DataSet;
            NationsGrid.DataSource = ds.DefaultViewManager;
            NationsGrid.DataMember = "Nation";
        }


De Grid bestaat uit een Textveld, 2 velden met dropdowns, en een checkbox veld, inititeel ziet dat er ook netjes uit. Echter als ik XML nog een keer bind aan de Datagrid, dan is alles een textfield. Kan iemand mij zeggen wat ik hier aan kan doen? Ik vermoed dat ik de Datagrid moet herinitialiseren, maar kan op dit moment geen geschikte method vinden die dit bewerkstelligt.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Er is toch een DataSourceInitialized/Changed (of weet ik het wat) event :?
Heb 't even niet bij de hand hier en nu, maar het moet geen rocket science zijn om dat te vinden in MSDN ofzo.

[ Voor 50% gewijzigd door RobIII op 14-07-2008 13:50 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


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

Niemand_Anders

Dat was ik niet..

De DataGrid 'herlaad' alleen als het een nieuwe dataset reference krijgt toegewezen. Op dat moment zal ook het DataSourceChanged event worden afgevuurt.

Alleen opnieuw ReadXml aanroepen is niet voldoende, omdat daarmee alleen de inhoud van de dataset zelf wijzigt, wat niet aan de datasource consumer wordt doorgegeven. DataGrid.DataSource is van het type 'object' en dat betekend helaas dat alleen een ander object als toewijzing gezien wordt als een Changed.

Wat mij nog niet duidelijk is is of je nogmaals Load_Xml() aanroept of alleen een nieuwe 'NationsGrid.DataSource = ' call uitvoert.

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


  • raptorix
  • Registratie: Februari 2000
  • Laatst online: 17-02-2022
Ik roep nog een keer Load_XML() aan, maar eigenlijk doet het probleem zich ook al voor als ik een rowfilter toepas, want dan gaat het ook al mis...
Ook dan veranderen de dropdowns in text velden..

Dit is complete 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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Xml;

namespace AllianceAdmin
{

    public partial class Form1 : Form
    {
        DataSet ds = new DataSet("NationsDS");
        public Form1()
        {
            InitializeComponent();
            Load_Xml();
        }
        private void Load_Xml()
        {
            XmlDataDocument xmlDatadoc = new XmlDataDocument();
            xmlDatadoc.DataSet.ReadXml("nations.xml");
            ds = xmlDatadoc.DataSet;
            NationsGrid.DataSource = ds.DefaultViewManager;
            NationsGrid.DataMember = "Nation";
        }


        private void Save_Click(object sender, EventArgs e)
        {
            DataViewManager dsgrid = (DataViewManager)NationsGrid.DataSource;
            dsgrid.DataSet.WriteXml("nations.xml", XmlWriteMode.IgnoreSchema);

        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (listBox1.SelectedItems.Count == 0)
            {
                MessageBox.Show("Select at least 1 resource");
            }
            if (listBox1.SelectedItems.Count > 2)
            {
                MessageBox.Show("Select 1 or 2 resources");
            }

            if (listBox1.SelectedItems.Count == 1)
            {
                ds.Tables[0].DefaultView.RowFilter = "resource1 like '" + listBox1.SelectedItems[0] + "' or resource2 like '" + listBox1.SelectedItems[0] + "'";
                Save.Enabled = false;
                NationsGrid.DataSource = ds.Tables[0];
                NationsGrid.ReadOnly = true;
            }
            if (listBox1.SelectedItems.Count == 2)
            {
                ds.Tables[0].DefaultView.RowFilter = "(resource1 like '" + listBox1.SelectedItems[0] + "' and resource2 like '" + listBox1.SelectedItems[1] + "') or (resource1 like '" + listBox1.SelectedItems[1] + "' and resource2 like '" + listBox1.SelectedItems[0] + "')";
                Save.Enabled = false;
                NationsGrid.DataSource = ds.Tables[0];
                NationsGrid.ReadOnly = true;
            }
        }

        private void Reset_Click(object sender, EventArgs e)
        {
            Load_Xml();
            Save.Enabled = true;
            NationsGrid.ReadOnly = false;
        }
    }
}

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

Niemand_Anders

Dat was ik niet..

Volgens mij worden alles als label weergegeven doordat je het grid readonly maakt en wijzigingen (dus ook geen andere dropdown selectie) niet zijn toegestaan.

Uit de MSDN (DataGrid.Readonly - sectie remarks):
In read-only mode, the grid can be scrolled, nodes can be expanded or collapsed, and so on. However, no additions, edits, or deletes can take place.

The DataGridColumnStyle also has a ReadOnly property that can be set to true to prevent data from being edited, on a column-by-column basis.

The ReadOnly can be set to true if you want to prohibit the user from editing the data directly in the System.Windows.Forms..::.DataGrid. For example, you might want to let users to see all columns in a table, but allow them to edit specific fields only through TextBox controls on a different form.
Je zult dus het readonly veld per column moeten zetten wil je dan de controls niet allemaal naar een label veranderen. Althans zo heb ik het even snel gelezen.

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


  • raptorix
  • Registratie: Februari 2000
  • Laatst online: 17-02-2022
Mmmmm ook als ik dat uitcommentarieer blijft het probleem zich voordoen ;(

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 09:22

TeeDee

CQB 241

raptorix schreef op maandag 14 juli 2008 @ 15:57:
Mmmmm ook als ik dat uitcommentarieer blijft het probleem zich voordoen ;(
Wat 'uitcommentarieer'?

Ben je al eens door de code heen gestepped??

Heart..pumps blood.Has nothing to do with emotion! Bored


  • raptorix
  • Registratie: Februari 2000
  • Laatst online: 17-02-2022
TeeDee schreef op maandag 14 juli 2008 @ 16:02:
[...]

Wat 'uitcommentarieer'?

Ben je al eens door de code heen gestepped??
NationsGrid.ReadOnly = true;
Mjah, kan er eens doorsteppen en wat watches zetten.

  • raptorix
  • Registratie: Februari 2000
  • Laatst online: 17-02-2022
Mmmm mjah het vreemde is dit, bij intitieele vulling heeft de Datagrid 5 columnitems, en deze zijn netjes van formaat wat je zou verwachten:

code:
1
2
3
4
5
6
7
-       items   Count = 5   
System.Collections.ArrayList
+       [0] {DataGridViewTextBoxColumn { Name=NationId, Index=0 }}  object {System.Windows.Forms.DataGridViewTextBoxColumn}
+       [1] {DataGridViewTextBoxColumn { Name=nationname, Index=1 }}    object {System.Windows.Forms.DataGridViewTextBoxColumn}
+       [2] {DataGridViewComboBoxColumn { Name=Resource1, Index=2 }}    object {System.Windows.Forms.DataGridViewComboBoxColumn}
+       [3] {DataGridViewComboBoxColumn { Name=Resource2, Index=3 }}    object {System.Windows.Forms.DataGridViewComboBoxColumn}
+       [4] {DataGridViewCheckBoxColumn { Name=intoTc, Index=4 }}   object {System.Windows.Forms.DataGridViewCheckBoxColumn}


Maar na de filteractie zijn ze veranderd in

code:
1
2
3
4
5
+       [0] {DataGridViewTextBoxColumn { Name=nationid, Index=0 }}  object {System.Windows.Forms.DataGridViewTextBoxColumn}
+       [1] {DataGridViewTextBoxColumn { Name=nationname, Index=1 }}    object {System.Windows.Forms.DataGridViewTextBoxColumn}
+       [2] {DataGridViewTextBoxColumn { Name=resource1, Index=2 }} object {System.Windows.Forms.DataGridViewTextBoxColumn}
+       [3] {DataGridViewTextBoxColumn { Name=resource2, Index=3 }} object {System.Windows.Forms.DataGridViewTextBoxColumn}
+       [4] {DataGridViewTextBoxColumn { Name=intoTc, Index=4 }}    object {System.Windows.Forms.DataGridViewTextBoxColumn}

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
raptorix schreef op maandag 14 juli 2008 @ 16:21:
Mjah, kan er eens doorsteppen en wat watches zetten.
Dat hoor je te doen voordat je een topic opent ;)
Verder zijn we ook niet blij met een topickick binnen 24 uur; let daar voortaan even op a.u.b. (maar dat weet je vast wel met ruim 10k posts op je kerfstok ;) )

[ Voor 7% gewijzigd door RobIII op 14-07-2008 16:36 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • raptorix
  • Registratie: Februari 2000
  • Laatst online: 17-02-2022
RobIII schreef op maandag 14 juli 2008 @ 16:35:
[...]

Dat hoor je te doen voordat je een topic opent ;)
Verder zijn we ook niet blij met een topickick binnen 24 uur; let daar voortaan even op a.u.b. (maar dat weet je vast wel met ruim 10k posts op je kerfstok ;) )
Het sloeg op de redactie van: Niemand_Anders, die suggereerde dat het zetten van de readonly mogelijk een probleem veroorzaakt, kortom het was niet een kick maar een zinvolle bijdrage tot het probleem, overigens zijn het er 12k posts ware het niet dat er 2000 kwijt zijn geraakt met BC3 ;)

Offtopic: Lijkt het maar zo, of wordt er tegenwoordig minder gepost op Programming?

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
raptorix schreef op maandag 14 juli 2008 @ 17:04:
Offtopic: Lijkt het maar zo, of wordt er tegenwoordig minder gepost op Programming?
offtopic:
Het is komkommertijd ja ;) Is ieder jaar zo rond deze tijd. En maar goed ook, kunnen wij ook eens met vakantie :P

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


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

Niemand_Anders

Dat was ik niet..

Heb je al .NET source code geinstalleerd op je PC (zie post van Shawn Burk voor configuratie van visual studio) zodat je ook door de Microsoft code kan steppen? Dat maakt het meestal iets gemakkelijker te begrijpen waarom iets niet werkt zoals je verwacht.

Mogelijk kun je dan achterhalen waar in het .net framework je columns worden vervangen. gaat de postback wel goed? Worden na de postback weer alle juiste columns gezet, of is de columns collectie leeg en valt het DataGrid terug naar de default textboxes?

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


  • raptorix
  • Registratie: Februari 2000
  • Laatst online: 17-02-2022
Niemand_Anders schreef op dinsdag 15 juli 2008 @ 10:09:
Heb je al .NET source code geinstalleerd op je PC (zie post van Shawn Burk voor configuratie van visual studio) zodat je ook door de Microsoft code kan steppen? Dat maakt het meestal iets gemakkelijker te begrijpen waarom iets niet werkt zoals je verwacht.

Mogelijk kun je dan achterhalen waar in het .net framework je columns worden vervangen. gaat de postback wel goed? Worden na de postback weer alle juiste columns gezet, of is de columns collectie leeg en valt het DataGrid terug naar de default textboxes?
Het is dus winforms, dus geen web, zoals bovenstaande debug info aangeeft is het aantal columns nog gelijk, enige verschil is dat ze dus van check/dropdown types veranderen in textfields....

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 09:22

TeeDee

CQB 241

- En als je expliciet cast om te zien of het ook dan werkt?
- View bijwerken?

Heart..pumps blood.Has nothing to do with emotion! Bored


  • raptorix
  • Registratie: Februari 2000
  • Laatst online: 17-02-2022
Mjah ga dat maar eens proberen.

  • Mastermind
  • Registratie: Februari 2000
  • Laatst online: 13-11 20:20
Niemand_Anders schreef op maandag 14 juli 2008 @ 14:19:
De DataGrid 'herlaad' alleen als het een nieuwe dataset reference krijgt toegewezen. Op dat moment zal ook het DataSourceChanged event worden afgevuurt.

Alleen opnieuw ReadXml aanroepen is niet voldoende, omdat daarmee alleen de inhoud van de dataset zelf wijzigt, wat niet aan de datasource consumer wordt doorgegeven. DataGrid.DataSource is van het type 'object' en dat betekend helaas dat alleen een ander object als toewijzing gezien wordt als een Changed.
Nee hoor, als je de DataSource wijzigt van een DataGrid zal de inhoud van de DataGrid meewijzigen.

Om te zorgen dat hij dezelfde layout pakt, moet je een Layout eventhandler aanmaken.

C#:
1
2
3
4
5
6
7
8
9
10
private void BindGrid()
{
DataGrid dg = new DataGrid();
            dg.Layout += new LayoutEventHandler(dg_Layout);
}

private void dg_Layout(object sender, LayoutEventArgs e)
{
// Stel hier de Layout in.
}

  • raptorix
  • Registratie: Februari 2000
  • Laatst online: 17-02-2022
Maar dat is toch vaag, de layout van de Datagrid wijzigt toch niet? Logischerwijs zou het toch te gek voor woorden zijn dat als je een RowFilter hanteert, dat je dan de layout handmatig zou moeten zetten.....

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

Niemand_Anders

Dat was ik niet..

Mastermind schreef op dinsdag 15 juli 2008 @ 13:04:
[...]

Nee hoor, als je de DataSource wijzigt van een DataGrid zal de inhoud van de DataGrid meewijzigen.
Om te zorgen dat hij dezelfde layout pakt, moet je een Layout eventhandler aanmaken.
Uit de Microsoft Shared Code release:
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
[SRCategory("CatData"), RefreshProperties(RefreshProperties.Repaint), TypeConverter("System.Windows.Forms.Design.DataSourceConverter, System.Design, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), DefaultValue((string) null), SRDescription("DataGridDataSourceDescr")]
public object DataSource
{
    get
    {
        return this.dataSource;
    }
    set
    {
        if (((value != null) && !(value is IList)) && !(value is IListSource))
        {
            throw new Exception(SR.GetString("BadDataSourceForComplexBinding"));
        }
        if ((this.dataSource == null) || !this.dataSource.Equals(value))
        {
            if (((value == null) || (value == Convert.DBNull)) && !"".Equals(this.DataMember))
            {
                this.dataSource = null;
                this.DataMember = "";
            }
            else
            {
                if (value != null)
                {
                    this.EnforceValidDataMember(value);
                }
                this.parentRows.Clear();
                this.originalState = null;
                this.caption.BackButtonActive = this.caption.DownButtonActive = this.caption.BackButtonVisible = false;
                this.caption.SetDownButtonDirection(!this.layout.ParentRowsVisible);
                this.Set_ListManager(value, this.DataMember, false);
            }
        }
    }
}


Ofwel als je alleen de data in een object wijzigt en opnieuw het object toewijst (regel 14) zal this.dataSource.Equals(value) true zijn en daardoor ziet het grid simpelweg niet dat er veranderingen zijn. Set_ListManager wordt dus niet aangeroepen en de veranderingen worden dus niet doorgevoerd.

De eenvoudigste workaround is om de datasource aan de ctor van een nieuwe datasource instantie mee te geven. Probleem is namelijk dat DataSet.Equals geen eigen implementatie heeft en dus de implementatie van object erft. Ook List<T> heeft geen eigen Equals implementatie..

Uit de remarks sectie van Object.Equals
The default implementation of Equals supports reference equality for reference types, and bitwise equality for value types. Reference equality means the object references that are compared refer to the same object.
Dat betekend dus zolang het DataSet object zelf niet opnieuw wordt aangemaakt de reference niet wijzigt en daarmee geeft equals dus 'true' terug als de DataSet 'opnieuw' aan het grid wordt gekoppeld.

C#:
1
2
3
4
5
6
7
8
9
10
List<int> list = new List<int>();
list.Add(1); // 

grid.DataSource = list; // <-- eerste toewijzing

list.Add(2); // <-- object (grid.DataSource) heeft geen implementatie van INotifyPropertyChanged dus DataSource weet niet dat de list is gewijzigd, zelfs als List<T> INotifyPropertyChanged zou implementeren.

grid.DataSource = list; // <-- list heeft nog steeds hetzelfde reference en DataGrid refreshed niet.
list = new List<int>(list); //zorgt voor nieuw object referentie
grid.DataSource = list; // <-- deze toewijzing zorgt wel voor een refresh van het datagrid.


Hoop dat ik duidelijker hen kunnen maken waarom het opnieuw inlezen van de xml dmv ReadXml niet voldoende is voor DataGrid.DataSource om het als een nieuwe data source te zien. Overigens heeft dit verder weinig te maken waarom de columns van de TS veranderen naar het type DataGridTextBoxColumn.

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


  • raptorix
  • Registratie: Februari 2000
  • Laatst online: 17-02-2022
Thx, ik kreeg gelijkertijd deze tip van iemand op MSN :)

  • PhoneTech
  • Registratie: Mei 2000
  • Laatst online: 17-11 08:46
En dat te bedenken dat ik heel weinig ervaring heb met C# en nu al jaar of 5 met java bezig ben :)

  • Mastermind
  • Registratie: Februari 2000
  • Laatst online: 13-11 20:20
Sorry ik was in de war met de UltraGrid. Die wordt wel geupdate als je in het object waaraan deze gebound is iets verandert.
Pagina: 1