DataGridView questions RRS feed

  • Question

  • Hi there,

    This is my first post here, I hope it is OK and that I am explain myself well! 

    I have a couple of queries.  Firstly a bit of background:  I have an application which reads an XML Datafile, and creates from that, a strongly typed object representation of it, which I then keep in a singleton class so it can be accessed from all around my application regardless of form, class, etc. 

    I am trying to display the transaction "node" of data from this object in a DataGrid in a format that closely matches an application my company used previously.  I am not auto-generating columns as I only need a few of the many that are in the object.  So I am using DataGridViewTextBoxColumns to specify what I want, like this:

      DataGridViewTextBoxColumn transNoColumn = new DataGridViewTextBoxColumn();
      transNoColumn.DataPropertyName = "TransactionNumber";
      transNoColumn.HeaderText = "Trs Num";
      transNoColumn.ValueType = typeof(int);
      transNoColumn.Width = 73;

    First question is this:  I am trying to sort the data by a field: TransactionNumber.  I found that by simply binding the DataGridView to the objects Transaction Node thus:

      dgvTransactionData.AutoGenerateColumns = false;
      dgvTransactionData.DataSource = myClass.Data.Transactions;
    it simply populated the rows in the order directly from the object, which aren't necessarily in the order I wanted.  So I tried to use a DataView to sort the data first.  In order to get this to work, I found I had to jump through a few hoops to get the object data into the dataview:

      XmlSerializer mySerializer = new XmlSerializer(typeof(myData));
      StringWriter sw = new StringWriter();
      mySerializer.Serialize(sw, myData.Data);
      DataSet ds = new DataSet();
      ds.ReadXml(new StringReader(sw.ToString()));
      DataView dv = new DataView(ds.Tables["Transaction"]);
      dv.Sort = "TransactionNumber DESC";
    And then I set the datasource of the DataGridVew to dv instead.  However, the TransactionNumber field is now "alphabetic", as it was serialised from the object to XML to get into the DataSet.  And so my table is now being populated like this:



    So, how can I change this to be correctly numerically sorted??  I am setting the ValueType property of the column as you can see in the first code snippet above, but it does not seem to work.


    Second question is this:

    I have two columns in my row: "Debit" and "Credit".  The values for these come from the SAME property of the object (or node of XML if you like), which is TransactionValue.  In the originally typed object this is a Decimal value.  If it is a positive figure, I want the value to show under the Debit column, and for the Credit column to show 0.00.  If it is a negative value (ie. < 0) I want to show it under the Credit column, and for the Debit column to show 0.00 instead. 

    So I have defined my columns thus:

      DataGridViewTextBoxColumn debitColumn = new DataGridViewTextBoxColumn();
      debitColumn.DataPropertyName = "TransactionValue";
      debitColumn.HeaderText = "Debit";
      debitColumn.ValueType = typeof(string);
      debitColumn.Width = 70;
      debitColumn.CellTemplate.Style.ForeColor = Color.Red;     
      DataGridViewTextBoxColumn creditColumn = new DataGridViewTextBoxColumn();
      creditColumn.DataPropertyName = "TransactionValue";
      creditColumn.HeaderText = "Credit";
      creditColumn.ValueType = typeof(string);
      creditColumn.Width = 70;
      creditColumn.CellTemplate.Style.ForeColor = Color.Blue;
    So you see it's two columns, with different headers, but the same source...  I know I've got it set as a string but I am playing about with it at the moment.. 

    So when the DataGridView is shown, the same value is shown for both Debit and Credit.

    To try and fix this, after my binding of dv as the DataSource, I have the following code:

      for (int i = 0; i < dgvTransactionData.Rows.Count; i++)
        if (Convert.ToDecimal(dgvTransactionData.Rows[i].Cells[3].Value) < 0)
          dgvTransactionData.Rows[i].Cells[3].Value = 0;
    The idea being that it loops through each row checking if the Debit Column is negative, and setting it to zero if need be.

    This does actually work, HOWEVER, it's ALSO resetting the Credit column value to 0 too!!!  I presume this is done because they are sourced from the same field in the DataSet... But I am not changing the DataSet, only the column in the DataGrid.  So I dont know why it would change the other field, unless they are still linked at this point and the DataGridView is changing its source at the same time??

    Can anyone advise how I might get around this please and be able to manually set each field individually?


    Sorry for the long email, I hope it made sense and I look forward to hearing back from any of you.



    • Moved by CoolDadTx Tuesday, April 7, 2009 1:30 PM WinForms related
    Tuesday, April 7, 2009 10:55 AM

All replies

  • 1. Did you try LinQ to sort?

    2. Again can we use LinQ to create required columns like debit/credit in the dataset itself?
    Friday, April 10, 2009 6:40 AM
  • Hiya

    Well I ended up sorting out the second question by going back to the original class and splitting the value into two distinct columns, then in the population of those original columns, doing the logic to put a value or not..  Was the easiest way I could think of...

    But the first problem remains -- how do I sort the rows numerically by TransactionNumber? They are still coming out sorted alphabetically as above - regardless of what I try! I am not sure how to use LINQ to do this... Please help!! :(


    Mike :)
    Friday, April 10, 2009 10:42 AM
  • Monday, April 13, 2009 12:11 AM