Presenting Detail Values as Part of the Master – part 3

By Bill at September 04, 2009 15:39
Filed Under: .Net Programming

This is part three of a three part series on working with master-detail data.  In part one I showed how to present detail values on the master using a utility I wrote called the SubPropertyAccessor. In part two I showed how the SubPropertyAccessor works. In this part, I introduce a descendant of DataGridViewColumn that will allow us to show the indexed detail data in line with the master data as additional columns.  I also introduce a descendent of TypeDescriptionProvider that allows the DataGridView to see the SubProperty as a proper property so that the rest of the grid functionality will still work.

Note: The SubPropertyAccessor was called SubAttributeAccessor in parts one and two.

SubPropertyColumn

The whole point of having detail values appear as part of a master record is to show the data in a grid where the detail values would appear in columns next to the other properties in the record.  In order to do this I created a descendant of DataGridViewColumn called SubPropertyColumn.  Actually, SubPropertyColumn is a descendant of DataGridViewTextBoxColumn.  The DataGridViewTextBoxColumn has most of the functionality I want.  I only need to have the data marshaled in and out of the data bound item in a specific way.

The first thing we need is to know where the SubPropertyAccessor is on the data bound item.  This will be a property on the column that can be set at design time in the DataGridView designer.

  72:         /// <summary>
  73:         /// The name of the property that is the indexed property.
  74:         /// Note that for sorting to work this
  75:         /// should be set to 'Properties'
  76:         /// </summary>
  77:         [Category("Data"),
  78:         DefaultValue("Properties"),
  79:         Description("The name of the property that is the indexed property.")]
  80:         public string IndexedPropertyName {
  81:             get { return fIndexedPropertyName; }
  82:             set {
  83:                 fIndexedPropertyName = value;
  84:             }
  85:         }

Now that we know where to find the SubPropertyAccessor, we need to know which property we are looking for.  This is the index that we will pass into the SubPropertyAccessor.  We need another string property.

 114:         /// <summary>
 115:         /// The index to pass to the indexed property to get the value for this column.
 116:         /// </summary>
 117:         [Category("Data"),
 118:         DefaultValue(""),
 119:         Description("The index to pass to the indexed property to get the value for this column.")]
 120:         public string PropertyIndex {
 121:             get {
 122:                 return base.DataPropertyName;
 123:             }
 124:             set {
 125:                 base.DataPropertyName = value;
 126:             }
 127:         }

This property doesn’t have any backing data of its own.  It is using the DataPropertyName of the base DataGridViewTextBoxColumn.  We do this because the base DataGridColumn bases a lot of functionality on the DataPropertyName property.  For example, if this property is blank the base DataGridColumn doesn’t consider the column to be a data bound column.  If we are going to make use of the functionality provided by the base classes, we going to have to make them happy.  This may seem like a kludge, but it’s better than having to reinvent the DataGridColumn.

More...

kick it on DotNetKicks.com

Presenting Detail Values as part of the Master – part 2

By Bill at May 10, 2009 19:59
Filed Under: .Net Programming

This is part two of a three part series on working with master-detail data.  In part one I showed how to present detail values on the master using a utility I wrote called the SubAttributeAccessor.  In this article I will go into detail as to how the SubAttributeAccessor works. In part three, I’ll introduce a descendant of DataGridViewColumn that will allow us to show the indexed detail data in line with the master data as additional columns.

The SubAttributeAccessor is a class that when added to a parent class is able to present a list of children as an indexed property of the parent.  For example, let’s imagine that we had a class called song and that is has among other properties one that is a list of attribute objects.

public class Song {
public List<Attribute> Attributes {get; set;}
}

The attribute class on the other hand has at least two properties, a key and a value.  The key property is a string that will be used to identify the attribute and the value property would hold the actual value of the attribute.  Rather than a certain type or even an object, the value will hold a byte buffer where we can store anything using serialization.
 
public class Attribute {
public string Key {get; set;}
public byte[] Value {get; set;}
}

These two classes form the basis of the imaginary scenario that I used in part one of this article.  A song can have an unlimited number of attributes.  As things stand, we can add an attribute to a song like so:

Song mySong = new Song();
Attribute myAttribute = new Attribute();
myAttribute.Key = "Tempo";
myAttribute.Value = "slow";
mySong.Attributes.Add(myAttribute);

More...

kick it on DotNetKicks.com

Arithmetic in Generic Classes

By Bill at February 17, 2009 18:33
Filed Under: .Net Programming

I work quite a bit with matrices. I work with them enough that at some point I decided to create my own generic classes for a matrix and a half matrix. Among other things, I wanted my classes to provide a method to calculate the sum of items in a row or column. I immediately had a problem. How does one calculate the sum of two generic objects?

 To simplify things, let's say that we're working with a descendant of List<T> and we want to add a method called Sum().

We start by deriving a class from List<T>:

class SummableList : List{}

Let's go ahead and add the Sum()method:

class SummableList : List {
public T Sum() {
T result = default(T);
foreach (T item in this)
result += item;
return result;
}
}

Unfortunately, that will not compile.  It won't compile because the compiler doesn't know how to add two objects together.  In .Net a type parameter (the T in List<T>) that is not constrained is assumed to be of type System.Object and there's not much you can do with a plain old object.

More...

kick it on DotNetKicks.com

Authors

  RSS Feed Bill Fugina

Bill is Director of Technology for Coleman Insights. He enjoys programming, software design, walking, reading, dining out and watching movies, most of which he enjoys even more when he doing them with his wife, Deb, and or his son, Isaac.  Bill and Isaac are working on a video game, but they haven't made very much progress yet.

  RSS Feed Debra Hill

Deb dabbled in Project Management in the Advertising industry for (too) many years. She has happily ditched that and is taking some time to decide what is next career-wise. She enjoys gardening, knitting, sewing and various other crafty things. She also enjoys vegetating on the weekends with the family.

RSS Feed Isaac Hill-Fugina

Isaac has his own blog called Isaac's Place.

Recent Comments

Comment RSS

Bill's Run.GPS Stats

Training Sessions 16
Total Distance 50.17 mi
Total Time 0.11:50:02
Calories 6961 kcal
Average Speed 4.24 mph
Min Altitude -157 ft
Max Altitude 590 ft
Total Ascent 226 ft
Total Descent 236 ft