Build Your Own Custom Controls for WPF & Silverlight Data Binding
As posted in our previous articles, Visual Studio 2010 offers “Drag and Drop Data Binding” for WPF and Silverlight Applications. Using this feature, you can create data-bound controls by dragging items from the Data Source Window to the WPF or Silverlight Designer. As you’ve probably noticed, in Data Source Window you can select the item and choose the control to be generated. In the following drop-down menu, we have added some frequently used controls.
However, you are not limited to the default control list. You can click the “Customize…” button and launch the “Customize Control Binding” dialog in which you are allowed to choose more controls. Now you may ask if you can add other custom controls in the dialog. To answer this question, let’s explain a little bit how “Customize Control Binding” dialog identifies controls to be used in WPF or Silverlight Data Binding.
Basically, “Customize Control Binding” dialog checks each WPF or Silverlight control in the ToolBox window and looks for the corresponding design-time binding attributes that can be DefaultBindingPropertyAttribute, ComplexBindingPropertiesAttribute or LookupBindingPropertiesAttribute. If one or more binding attributes are detected on the control, “Customize Control Binding” dialog will include it in the list. In the later “Drag and Drop Data Binding”, we will generate the binding on the control according to the binding attributes. We also follow the priority rule (LookupBindingPropertiesAttribute > ComplexBindingPropertiesAttribute > DefaultBindingPropertyAttribute) to differentiate between different binding attributes on the same control.
Simply put, if you want to use your own custom control in “Drag and Drop Data Binding”, you need to implement binding attributes on the control and add the control to the ToolBox window. There are many online articles about how to add design-time attributes for WPF and Silverlight controls. Karl Shifflett has written a good series of articles on this: Extensibility Series – WPF & Silverlight Design-Time Code Sharing – Part I
In this article we will implement a WPF sample control to show how to use it in “Drag and Drop Data Binding”.
First, we create a WPF Custom Control Library named SampleControlLibrary and implement a SampleControl in which we define a Dependency Property (Test).
Public Class SampleControl
Inherits Control
Public Shared TestProperty As DependencyProperty = DependencyProperty.Register("Test", GetType(String), GetType(SampleControl), Nothing)
Public Property Test() As String
Get
Return CType(GetValue(TestProperty), String)
End Get
Set(ByVal value As String)
SetValue(TestProperty, value)
End Set
End Property
End Class
For WPF controls, there are two methods to define the binding attributes. One is to add it as normal attribute with the control. The snippet below shows defining the DefaultBinding on Test property.
Imports System.ComponentModel
<DefaultBindingPropertyAttribute("Test")> _
Public Class SampleControl
Inherits Control
However, since Silverlight3 doesn’t have a binding property class, the above method doesn’t work for Silverlight controls. Another way is to define the binding attributes in a separate Design-Time assembly (You can find more details about Design-Time assemblies here). The method applies to both WPF and Silverlight controls. For the above control, we create a Class Library named SampleControlLibrary.Design and add a reference to the control project. We also need to add reference to Microsoft.Windows.Design.Extensibility.dll. Then we add a class to implement IProvideAttributeTable in which we add a DefaultBinding attribute on Test property.
Imports Microsoft.Windows.Design.Metadata
<Assembly: ProvideMetadata(GetType(SampleControlLibrary.Design.SampleControlDesign))>
Public Class SampleControlDesign
Implements IProvideAttributeTable
ReadOnly Property AttributeTable As AttributeTable Implements IProvideAttributeTable.AttributeTable
Get
Dim builder As New AttributeTableBuilder()
builder.AddCustomAttributes(GetType(SampleControlLibrary.SampleControl), New System.ComponentModel.DefaultBindingPropertyAttribute("Test"))
Return builder.CreateTable()
End Get
End Property
End Class
Once we add the control to the ToolBox window (If you use Design-Time assembly, you need to put it in the same folder of the control assembly), we can see it shows up automatically on the “Customize Control Binding” dialog.
After Drag-Drop items are associated with the SampleControl, you will see that it’s generated with the correct data binding on the Test property when you drop it onto the design surface from the Data Sources window.
Cheers!