Naughton Futilities

No Relation

Silverlight 3 DataForm Control Mapping - Add Extensibility

An earlier posting explains how to perform basic modifications to the Silverlight 3 DataForm control.

http://weblogs.asp.net/naughton/archive/2009/08/01/silverlight-3-dataform-control-mapping-basic-modifications.aspx

It's convenient if such features are available for extensibility.

This can be achieved in a straightforward fashion too. (A modified DataForm project is attached.)

The DataForm implements the GenerateField method, which calls the two methods that affect Control mapping.
Control control = GetControlFromType(propertyType);

DependencyProperty dependencyProperty = GetBindingPropertyFromType(propertyType);

We can refactor this area, by introducing a Control Mapping interface (IControlMapper) and a default implementation (ControlMapper).

Note: I wanted access to the Custom Attributes on each Property, since Custom Attributes may contain information that influences the Control Mapping process. As such, I tweaked the GenerateField method signature to accept the PropertyInfo for the current Property.

We add a property to DataForm:

public IControlMapper ControlMapper { get; set; }

The GenerateField calling code then changes to the following:

private bool GenerateField(PropertyInfo propertyInfo, Type propertyType, string propertyName, BindingMode bindingMode, Panel panel)

...

IControlMapper controlMapper = this.ControlMapper;
if (null == controlMapper)

{

controlMapper = new ControlMapper();

}

controlMapper.PropertyInfo = propertyInfo;

controlMapper.PropertyType = propertyType;

Control control = controlMapper.GetControl();

DependencyProperty dependencyProperty = controlMapper.GetBindingProperty();

...

We can now define a derived DataForm class that supplies a different implementation of IControlMapper that performs the required mapping.

public interface IControlMapper

{

PropertyInfo PropertyInfo { get; set; }

Type PropertyType { get; set; }

Control GetControl(); DependencyProperty GetBindingProperty();

}

Here is the refactored ControlMapper base class:

public class ControlMapper : IControlMapper

{

#region IControlMapper Members

protected PropertyInfo propertyInfo;

public PropertyInfo PropertyInfo

{

get

{

return this.propertyInfo;

}

set

{

this.propertyInfo = value;

}

}

protected Type propertyType;public Type PropertyType

{

get

{

return this.propertyType;

}

set

{

this.propertyType = value;

}

}

public virtual Control GetControl()

{

Type type = this.PropertyType;

Debug.Assert(type != null, "The type must not be null.");

if (type == typeof(bool))

{

return new CheckBox();

}

else if (type == typeof(bool?))

{

CheckBox checkBox = new CheckBox();

checkBox.IsThreeState = true;

return checkBox;

}

else if (type == typeof(DateTime) || type == typeof(DateTime?))

{

return new DatePicker();

}

else if (type.IsEnum)

{

ComboBox comboBox = new ComboBox();

FieldInfo[] valueFieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.Static);

List<string> valueList = new List<string>();foreach (FieldInfo valueFieldInfo in valueFieldInfos)

{

Enum value = valueFieldInfo.GetValue(null) as Enum;

if (value != null)

{

valueList.Add(value.ToString());

}

}

comboBox.ItemsSource = valueList;

return comboBox;

}

else

{

return new TextBox();

}

}

public virtual DependencyProperty GetBindingProperty()

{

Type type = this.PropertyType;

Debug.Assert(type != null, "The type must not be null.");

if (type == typeof(bool) || type == typeof(bool?))

{

return CheckBox.IsCheckedProperty;

}

else if (type == typeof(DateTime) || type == typeof(DateTime?))

{

return DatePicker.SelectedDateProperty;

}

else if (type.IsEnum)

{

return ComboBox.SelectedItemProperty;

}

else

{

return TextBox.TextProperty;

}

}

#endregion

}

 

Comments

Naughton Futilities said:

A recent post described how to obtain extensibility, with respect to DataForm Control Mapping: http:

# August 1, 2009 12:59 PM

Silverlight 3 DataForm Control Mapping – Add Extensibility | ASP Scribe said:

Pingback from  Silverlight 3 DataForm Control Mapping &#8211; Add Extensibility | ASP Scribe

# August 1, 2009 2:13 PM

brainbox said:

Hi,

I strongly suggest you to use some code snippet plugin. All code you have showed is unreadable.

Goog luck,

Alexey Zakharov.

# August 3, 2009 2:34 PM

Jay Dixit said:

I have creating application using DataForm control but while i m running it; it showing an error as below

System.TypeLoadException: Could not load type 'System.ComponentModel.BindableAttribute' from assembly 'System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.

   at System.Windows.Controls.DataForm.GenerateFields()

   at System.Windows.Controls.DataForm.OnAutoGenerateFieldsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

   at System.Windows.DependencyObject.RaisePropertyChangeNotifications(DependencyProperty dp, Object newValue, Object oldValue)

   at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, Boolean allowReadOnlySet, Boolean isSetByStyle, Boolean isSetByBuiltInStyle, PropertyInvalidationReason reason)

   at MS.Internal.FrameworkCallbacks.SetValueCustom(IntPtr nativeRoot, IntPtr nativeTarget, UInt32 propertyId, String attrValue, CValue& propertyValue, Int32 typeIndex, Boolean isSetByStyle, Boolean isSetByBuiltInStyle, PropertyInvalidationReason reason) [Line: 0 Position: 0]

   --- Inner Exception ---

Could not load type 'System.ComponentModel.BindableAttribute' from assembly 'System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.

Please let me know if i m doing some thing wrong.

i followed the steps what is available in the Silverlight videos.

Thanks in Advance

Jay

# November 16, 2009 10:32 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)