Most of the steps in
configuring the control are the same
for every control type, so those have
been factored into the reusable ConfigureAndBindControl()
method. For the TextBox, the only idiosyncratic
step is that of setting the width.
We can definitely get more sophisticated
about that than we’ve done here
and some control types will require
a bit more setup, but you get the idea.
Binding the Dynamic Properties
All of the code above, beginning
with the declaration of the DelegateHolder,
relates to creating the databinding
for the dynamic property. To accomplish
that binding, we must first create
a System.ComponentModel.PropertyDescriptor
for the new property, and then add
that to the set of descriptors for
the type on which we want the dynamic
property maintained (in this case,
Employee).
We get the necessary PropertyDescriptor
by constructing an IdeaBlade.Util.AdaptedPropertyDescriptor.
Its constructor needs the following
pieces of information:
- A name for the new property
(supplied above as pColumn.ColumnName)
- The type on which the new property
will be defined (Employee)
- The property’s data type
(pColumn.DataType)
- A delegate instance that will
return a value when the property’s
value is requested
- A delegate instance that will
set the property’s value.
We’ll discuss the two delegate
instances in a moment, but for now
let’s continue with the last
two statements in ConfigureAndBindControl().
The statement
mEmployees.AddPropertyDescriptor(aDescriptor)
adds the PropertyDescriptor just
created to the list maintained by
the mEmployees EntityList. That list
might be entirely specific to the
mEmployees EntityList; or it might be
centrally maintained for use by all
lists of Employees used by your application.
In this case, take our word for it
that we said nothing in the configuration
of the mEmployees EntityList to tell
it to use a private PropertyDescriptorList.
So, by default, it uses the global
list. As such, when we add the new
PropertyDescriptor as we have done
above, we are in fact making the
new property available to all BindableLists
and EntityLists of Employees in our
app. Any BindableList or EntityList
of Employees subsequently declared
tells whomever asks that the set
of properties maintained on Employee
objects includes the dynamically
defined one(s).
To divert into a discussion of
private PropertyDescriptorLists would
take this article in yet another
direction, so we will defer that
to another time and another place.
We hope it will suffice for now to
say that it is possible to define
a dynamic property on a type only
in connection with a single specific
BindableList or EntityList rather
than for all lists containing that
type, that there are some specialized
use cases for that, and that we don’t
need to use this facility for our
purposes here.
Adding the BindingDescriptor
to the BindingManager’s Collection
The final statement in ConfigureAndBindControl()
creates a BindingDescriptor for the
dynamic property and adds it to the
Descriptors collection of an IdeaBlade.UI.Winforms.ControlBindingManager
named “mEmployeeCBM”:
Me.mEmployeeCBM.Descriptors.Add(pControl,
pColumn.ColumnName)
Note that mEmployeeCBM consults something to
determine if the property named with
the value returned by pColumn.ColumnName
actually exists. If the mEmployeeCBM’s
BindingSource has already been configured,
it consults the list that supplies
the BindingSource. If not, it consults
the global PropertyDescriptorsList.
If the list consulted says the property
exists, the binding configures; otherwise,
it fails.
Supplying the Delegate
Instances for the AdaptedPropertyDescriptor
Constructor
There’s just one last detail
to clear up. If you recall, we instantiated
a DelegateHolder object, referencing
the Getter and Setter delegates needed
by the constructor of AdaptedPropertyDescriptor()
as members thereof. We did that in
order to be able to get the name
of our dynamic property into the
delegates as a variable (since we
can’t change their signatures!).
The code is shown below.
|