Property Grid Default Values

rbulph

Junior Contributor
Joined
Feb 17, 2003
Messages
397
Is there any way that I can get the property grid to forget the idea of showing non-default values in bold? Not every property logically has a default value, and I find it distracting that, for me, the column with the values is all bold, because I don't have any default values. I was wondering if I might be able to substitute all property descriptors for custom ones which inherit from PropertyDescriptor, and override a function that determines whether the value is the default one, but had no success when I looked into this. Any other ideas?
 
I can show you how I check an individual cell for content and change the color and then it could give you an idea what to do from there if you like?
 
techmanbd said:
I can show you how I check an individual cell for content and change the color and then it could give you an idea what to do from there if you like?
Yes, that would be very helpful, please. I can navigate the cells through the GridItems collection, starting with the SelectedGridItem, and can then get values using the GridItem's value property, but beyond that I wouldn't know how to go about what you do.
 
OK, here you go. In this example, You need to make a public class that inherits DataGridTextBoxColumn. Then on load up, I format the grid columns. If you notice, in my sub, The first column, It is a basic column because I am not changing colors in that one. It is just for frequencies. But the next 12 columns, I make from the public class. Since those are the ones I want to compare for color change. A little long, but hope this helps you get to what you need. My code is below, and here is a link to where I was able to get my color change in indivual cells from. They also have some format examples.
http://msdn.microsoft.com/library/d...tingWindowsFormsDataGridVisualBasicPrimer.asp


Visual Basic:
Public Class frmHBmain
    Inherits System.Windows.Forms.Form

Private Sub frmHBmain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.FormatGridColumns()
        Me.SetUpDatagrids()
End Sub

Private Sub FormatMyGrids
     Dim tsProducts As New DataGridTableStyle
        Dim tbcSerialNumber As DataGridTextBoxColumn
        Dim ctbcResult(12) As ColoredTextBoxColumnResult
        Dim intLoop As Integer
       tbcSerialNumber = New DataGridTextBoxColumn
       With tbcSerialNumber
               .MappingName = "frequency"
               .HeaderText = "Frequency"
               .Width = 60
               .Alignment = HorizontalAlignment.Center
       End With

        For intLoop = 1 To 12
            ctbcResult(intLoop) = New ColoredTextBoxColumnResult
            With ctbcResult(intLoop)
                .MappingName = "ch" & intLoop.ToString
                .HeaderText = "CH" & intLoop.ToString
                .Width = 40
                .Alignment = HorizontalAlignment.Center
            End With
  
        Next
        tsProducts.MappingName = "Vrms"
        tsProducts.GridColumnStyles.Add(tbcSerialNumber)
        For intLoop = 1 To 12
            tsProducts.GridColumnStyles.Add(ctbcResult(intLoop))
        Next
        Me.datResult.TableStyles.Add(tsProducts)

        tsProducts.Dispose()
end sub

 Private Sub SetUpDatagrids()
   
        Me.datResult.DataSource = Nothing
        Me.datResult.CaptionText = "Result in dBs"
        Dim objCellVal As Object
        Dim intLoop As Integer
        Dim intLoopChan As Integer
        For intX As Integer = 1 To 3
            Dim dt As New DataTable
            Dim dr As DataRow
            Dim dv As DataView = New DataView
            With dt
                .TableName = "Result"
                .Columns.Add("frequency")
                For intLoop = 1 To 12
                    .Columns.Add("ch" & intLoop.ToString)
                Next
            End With
            With dv
                .Table = dt
                For intLoop = 1 To 10
                    dr = .Table.NewRow
                    .Table.Rows.Add(dr)
                Next
            End With

            With Me.datResult
                .DataSource = dv
                'In here I have a some code that enters data into the cells of my grid
             end with
end sub

End Class

Visual Basic:
Public Class ColoredTextBoxColumnResult
    Inherits DataGridTextBoxColumn
    Dim passthru As PASSTHRUVARS
    Protected Overloads Overrides Sub Paint(ByVal graph As Graphics, _
         ByVal rectbounds As Rectangle, ByVal curmngrSrc As _
         CurrencyManager, ByVal RowNumber As Integer, ByVal _
         ForeColorBrush As Brush, ByVal BackColorBrush As Brush, _
         ByVal AlignmentRight As Boolean)

        Dim ObjVal As Object
        ObjVal = Me.GetColumnValueAtRow(curmngrSrc, RowNumber)
        If Not (IsNothing(ObjVal) Or IsDBNull(ObjVal)) Then
            If IsNumeric(ObjVal) Then
                Dim cellValue As Double = Convert.ToDouble(ObjVal)
                If cellValue = 0 Then
                    BackColorBrush = Brushes.LightGray
                    ForeColorBrush = Brushes.Black
                ElseIf (cellValue > Me.passthru.dblULVrms) Or (cellValue < Me.passthru.dblLLVrms) Then
                    BackColorBrush = Brushes.Red
                    ForeColorBrush = Brushes.Black
                Else
                    BackColorBrush = Brushes.Gray
                    ForeColorBrush = Brushes.Black
                End If
            Else
                BackColorBrush = Brushes.Gray
                ForeColorBrush = Brushes.Black
            End If
        Else
            BackColorBrush = Brushes.Gray
            ForeColorBrush = Brushes.Black
        End If
        ' Call Paint from the base class to 
        ' accomplish the actual drawing.
        MyBase.Paint(graph, rectbounds, curmngrSrc, RowNumber, _
            BackColorBrush, ForeColorBrush, AlignmentRight)
    End Sub
End Class
 
Thanks for posting this, but you do realise that I'm referring to the PropertyGrid, which is a specific control in the toolbox, don't you? It doesn't have a TableStyles property. So I can't see how I would use your code unfortunately.
 
A property is bold if it is supposed to be serialized and not bold if it is not supposed to be serialized. There is nothing you can do about that, but I think you can work with it. I know that this works with the property grid in the designer, but I'm not positive about the property grid in the toolbox. Suppose your property is named "Value". If you create a method with a boolean return type named "ShouldSerializeValue" the property grid will only bold the item in the grid if the method returns true.

For example, if you have two properties named DefaultValue and Value, and Value should only be serialized if it is different from DefaultValue, ShouldSerializeValue should be defined as follows:
Code:
[COLOR=Magenta]<C#>[/COLOR]
[COLOR=Blue]bool [/COLOR]ShouldSerializeValue(){
    [COLOR=Blue]return [/COLOR]Value != DefaultValue;
}

[COLOR=Magenta]<VB>[/COLOR]
[COLOR=Blue]Function [/COLOR]ShouldSerializeValue() [COLOR=Blue]As Boolean[/COLOR]
    [COLOR=Blue]Return [/COLOR](Value <> DefaultValue)
[COLOR=Blue]End Function[/COLOR]
If that fails, your class can implement ICustomTypeDescriptor, which takes a lot of work but makes the property grid very customizable.
 
Well in fact I already have a custom property descriptor class used for all my properties so all I need is to do this in that class:

Visual Basic:
    Public Overrides Function ShouldSerializeValue(ByVal component As Object) As Boolean
        Return False 
    End Function

This works perfectly to prevent things appearing in bold. What I find a bit puzzling is that serialization continues to work perfectly well in spite of me doing this, i.e. the classes can be saved no problem. I was thinking I would have to amend the return value of the function when serializing, but I don't. Maybe the name of the function isn't a very clear indication of what it actually does.
 
TypeDescriptors and ICustomTypeDescriptors are use for serialization in the designer (i.e. property grid), but not when using .Net classes to serialize an object. .Net serialization uses reflection, whereas TypeDescriptors provide another method of obtaining information about an object (although TypeDescriptors typically use reflection internally anyways).

To determine what is and isn't serialized you normally use (or don't) the NonSerialized attribute (System.NonSerializedAttribute).
 
Back
Top