Persist a value in an inherited class or create a custom parameter

Answered Persist a value in an inherited class or create a custom parameter

  • 15. dubna 2012 6:25
     
     

    Hi

    I am making some changes to a fairly old project.

    It has a DataGrid with an Inherited Class 

    Public Class CustomDataGridTextBox

              Inherits DataGridTextBoxColumn

    and a Override Sub

    Protected Overloads Overrides Sub Paint (.......

    What it was doing was alternating the Data Grid Line colours

    New Requirement is to break up some items in the DataGrid By categories

    So I have added new lines to the data and sorted so they show up ad category headers (Production Stations)

    And they would like the Category Header to be a different colour and then the alternating line colours to restart.

    This did not sound too difficult but that has proven a trap

    Setting the category header is no problem but restarting the alternating colours is

    Previously the row was determined to be odd or even to set the colour.

    Now I am intending to use an Integer to define what colour is used but it persists only for that text box.

    How can I get it to extend its life so each call can refer to it and update it and set the desired colour?

    All I need to do is have an integer variable that will hold its value for the next call?

    Thanks for any Assistance

    Doug

Všechny reakce

  • 15. dubna 2012 8:00
     
     Odpovědět

    All I need to do is have an integer variable that will hold its value for the next call?

    If this is really what you are trying to do, then declaring the variable as Static will solve the problem.
    http://msdn.microsoft.com/en-us/library/z2cty7t8(v=vs.100).aspx

  • 15. dubna 2012 20:46
     
     

    Hi Acamar,

    I just worked out that this was not my problem,

    The TextBoxColumn code Sub, as it says works on the columns. and holds the variable as it runs through each row. I have to find another way.

    Thanks for your reply

  • 15. dubna 2012 22:00
     
     Odpovědět

    In that case you may wish to provide a little more explanation.

    You were previously setting the color of the control according to whether the line number in the grid was odd or even.   I think the reason that this rule no longer works is that you want the first item within any category to be the same color - that's probably what you mean by 'restarting'.  If I was doing this I would simnply retain the old rule and accept that some categories will start with one color and other categories will start with a different color.  Whatever, it seems that you have decided to store the original line numbers (before the headers get added) as properties of the text box, and use those (as odd or even) to determine the coloring. 

    I think you are expecting a property of the custom text box class instance to be different for each cell that uses the class, and you will then color the cell according to that value.  To calculate that value, you would need to work through the rows in the grid assigning alternating numbers, and starting again after you hit a header cell.  Why use a value like that, when you could simply set the cell style properties, such as color?  Style properties, unlike the textbox instance, are unique to each cell.

  • 16. dubna 2012 0:45
     
     

    Thanks Acamar,

    I will look at that.

    Sorry I did not post some code, it is on another disconnected PC.

    Essentially you are correct:

    Header row Colour A

    First Data Row Colour B

    Second Data Row Colour C

    Subsequent Data Rows alternating B C B C etc

    then another Header Row and starting over B C B C etc

    I also understand what you are saying about retaining the old rule (I just felt it would look more professional to start each group the same way) and that would be a simpler solution.

    Thanks for your help, I will consider options.

    Doug

  • 16. dubna 2012 4:52
     
     

    HI,

    For this you can go with global class and use global variables into this class.

  • 5. května 2012 4:22
     
      Obsahuje kód

    Hi,

    I have got it partially working.

    The requirement is that the Grid will have 3 Row background Colours (in this case the set BackColor, the set AlternatingBackColor and a constant 'Salmon'

    That is working fine but my problem now is that clicking on a cell (which selects the row) or selecting the row from the Row Headers Column does not highlight the row correctly.

    It used to set a Dark Blue BackColor.

    Now it just inverts the text and it is not readable.

    I could not find why this changed but whenever there is a paint over-ride it does so I am assuming the paint over-ride is setting the cells (and consequently the row) to the colours the over ride paint event sets.

    OK so I figured I could force them to another colour in the same sub.

    I moved the Class Module into the Project and tried to reference the DataGrid but could not get that to work so I sent an integer in the form to the current row number

    And then tried to read that and compare with the paint 'rowNum' and then set the cell to another colour.

    This seemed to work as if I set the variable in the for to say Row 2 it does colour Row 2

    However if I set it using events in the form to the Row Number that is clicked etc it does not work

    The variable changes value in the form (checked but using a break point)

    But the variable in the Class Module does not reference this changed value (checked with Debug)

         

    Any ideas?

    Thanks

    'Over-ride Paint Method Protected Overloads Overrides Sub Paint(ByVal g As Graphics, _ ByVal bounds As Rectangle, ByVal source As CurrencyManager, _ ByVal rowNum As Integer, ByVal backBrush As Brush, _ ByVal foreBrush As Brush, ByVal alignToRight As Boolean) Static iRowColr As Integer = 0 Dim oVal As Object = Me.GetColumnValueAtRow([source], rowNum)

    Dim stVal As String = ""

    If Not oVal Is DBNull.Value Then

    stVal = oVal.ToString

    End If 'Dim dr As DataRow = CType(source.List().Item(rowNum), DataRowView).Row 'stVal = dr(1).ToString.Trim If bColourHeader Then If Me.HeaderText = "Wrk:" Then 'WorkStation Column If stVal <> stHdRow Then 'Is it 1st Row of WorkStation ie Header Row stHdRow = stVal 'Then Set Header Reference iRowColr = 0 'Set Row Colour Index to Header Colour Else 'Not 1st Row of Header If iRowColr = 0 Then 'If Index is Header Colour then set to Alternate Colour iRowColr = 2 ElseIf iRowColr = 1 Then 'If Index is Main Colour then set to Alt Colour iRowColr = 2 ElseIf iRowColr = 2 Then 'If Index is Alt Colour then set to Main Colour iRowColr = 1 End If End If ElseIf Me.HeaderText = "" Then 'Space Columns iRowColr = 2 ' set to Alt Colour Else ' Other Columns If stVal = "" Then iRowColr = 0 Else If iRowColr = 0 Then iRowColr = 2 ElseIf iRowColr = 1 Then iRowColr = 2 ElseIf iRowColr = 2 Then iRowColr = 1 End If End If End If Else If iRowColr = 1 Then iRowColr = 2 Else iRowColr = 1 End If End If End If Dim colBackCol As Color = Me.DataGridTableStyle.BackColor Dim colAltBackCol As Color = Me.DataGridTableStyle.AlternatingBackColor Dim colBreakCol As Color = Color.LightSalmon Dim bshBackColour As SolidBrush = New SolidBrush(colBackCol) Dim bshAltColour As SolidBrush = New SolidBrush(colAltBackCol) Dim bshBreakColour As SolidBrush = New SolidBrush(colBreakCol) Dim colSelCol As Color = Color.DarkGreen Dim bshSelColour As SolidBrush = New SolidBrush(colSelCol) Dim iSeldRow As Integer = FormShopOrders.iCurrRow

    If (iSeldRow > 0) And iSeldRow = rowNum Then

    backBrush = bshSelColour

    Else If iRowColr = -1 Then backBrush = bshSelColour ElseIf iRowColr = 0 Then backBrush = bshBreakColour ElseIf iRowColr = 2 Then backBrush = bshAltColour ElseIf iRowColr = 1 Then backBrush = bshBackColour End If

    End If MyBase.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight) End Sub


  • 5. května 2012 8:54
     
     

    I presume the variable you are referring to is iSeldRow.

    The class instance where this code is executing does not have any knowledge of or access to variables in the form unless you set the references up for it.   How you do that depends in part on how the class instance is created.  If it's created by code in the form (for instance at form load) or if it is a shared class then you can reference that class instance from the form - you have a reference variable for the class instance if you created the instance, or you use the class name as a reference if it is a shared class.   So you could create a class property, and update that property when the selected row changes using the class instance reference and the property name. 

    Then, the code in the overloaded Paint event can reference the internal class variable for that property to get the row number it needs.

    If my analysis of your code is correct you must have a declaration for the variable iSeldRow somewhere in that class - without it the code would not compile.   You need to remove that declaration, and change the code so it refers to the new property value instead.

  • 5. května 2012 12:33
     
     

    Hi Acamar,

    Thanks for your response,

    It does not seem to be correct to me that the Class Module does not have access to the variable because as you say later the code would not compile if it could not access the public variable in the Form. Maybe I have not understood what you are saying?

    Also as I said, if I initialise the variable in the form to a value say -1 or say 2 then the Class Module reacts appropriately to the value that I set.

    What doesn't happen is that as the variable, in Form Class, changes its value reflecting the selected row it does not change the value in the Class Module.

    Have I misunderstood something here?

    I would still like to understand this but I have managed to get a solution to the problem I was having. I realised that the row was being selected and then painted over by the new paint code. So instead of trying to determine if the row was the selected row, I looked at the backbrush property and if its colour = the colour set for the SelectedRow I then bypast the code that recoloured the row.

    Please continue to explain what is happening with the variable if I have missed something.

    Thanks

    Doug

  • 5. května 2012 13:31
     
     

    If you have a structure such as

    Class Form1
        Dim iSeldRow As Integer = 1
    End Class

    Class myModule
       If iSeldRow = ...
    End Class

    then the code will not compile.  If you give iSeldRow public visibility then you can do

    Class myModule
       If Form1.iSeldRow = ...
    End Class

    because you are providing a full reference to the variable (assuming the default instance name) .  If you can reference the variable using the code you posted then that code must have been inserted into the Form1 class, whereas you description implied it was still in its own module.   That's why I queried my analysis of your code - despite your reference to the 'Class Module' the fact that the code compiled indicated that you had actually merged the module code into the Form1 class, making your access to the variable legal (and telling you that the problem was elsewhere).

  • 5. května 2012 23:14
     
     

    Hi Acmar

    The code is not in the form it is in its ow Class Module within the Project:

    Solution '24x7Production' (...)

            .....

            .....

            - Production Recording

                  .....

                  - FormShopOrders.vb

                  .....

               - ClassSODataGrid

    _______________________________

      Public Class FormShopOrders

                 Public iCurrRow As Integer = 2      'Set to 2 to test that Integer is passed

            .........

            .........

                Private Sub grdSelSO_SetRow (ByVal iRow As Integer)

                     ' iCurrRow = iRow    'Remarked out whil testing variable value is past to Class

                End Sub

               .......

       End Class

     

    _____________________________________

       Public Class CustDGrid

            ......

       End Class

       Public Class CustTextBoxCol

            ......

           Protected Overloads Overrides Sub Paint(  ...,  ...., ....)

                ......

              Dim iSelRow As Integer = FormShopOrders.iCurrRow

               ......

          End Sub

       End Class

    Yes it compiles with no errors

    Setting iCurrRow to constant value of 2 then running the program, iSelRow gets set to 2

    But then if I un remark the code in FormShopOrders iCurrRow gets set to the row number on the grid when you click the grid

    but iSelRow is not updated it always holds its initial value.

    Thanks

  • 6. května 2012 0:44
     
     Odpovědět

    iSelRow is declared within the class in which it is being used so it will not cause a compile error.  The value you are setting it to corresponds to my second example where you explicitly reference the form instance that contains the variable:

              Dim iSelRow As Integer = FormShopOrders.iCurrRow

    However, FormShopOrders is a class name.  It is usable as an instance name if you are asuming the default instance.  That is usually an unsafe assumption, but may be OK in this case.

    Your testing is not telling you what you need to know.  Use code like this instead:
      Public Class FormShopOrders
                Public iCurrRow As Integer
                 ...
                Private Sub grdSelSO_SetRow (ByVal iRow As Integer)
                     ICurrRow = 2 'Set to 2 for testing, or
                     ' iCurrRow = iRow    'Set to row number for running
                End Sub

       End Class

    Then insert a breakpoint at the line that actually sets the value and make sure it gets set.