Custom Widget Provider
Make your custom widget available for selection in the data field editor
You can quickly replace the default widget on a data form with a custom one by modifying the data from markup.
However, if you want to make it available for selection as a standard widget in the data field editor, you should make and register a provider for the custom widget in C1 CMS.
The sample widget provider created below works specifically with these two sample text boxes:
- one with a picker button to invoke a standard dialog with a tree-like structure
- one with a picker button to invoke a custom dialog
Note: Add and register these custom text boxes to C1 CMS before taking the following steps.
Creating a custom widget provider
- In Visual Studio, create a Class Library project (e.g. “Composite.Samples.CustomWidgetProvider”).
- Add references to:
- System.Configuration
- ~\Bin\Composite.dll
- ~\Bin\Microsoft.Practices.EnterpriseLibrary.Common.dll
- ~\Bin\Microsoft.Practices.ObjectBuilder.dll
- Create a class for the widget function (e.g. ” SimpleTextWidgetFunction.cs”)
- Add the following code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; using Composite.C1Console.Elements; using Composite.C1Console.Security; using Composite.C1Console.Trees; using Composite.Core.Xml; using Composite.Functions; namespace Composite.Samples.CustomWidgetProvider { public class SimpleTextWidgetFunction : IWidgetFunction { public SimpleTextWidgetFunction(string name, string description) { Name = name; Description = description; } public XElement GetWidgetMarkup(ParameterList parameters, string label, HelpDefinition helpDefinition, string bindingSourceName) { return new XElement(Namespaces.BindingFormsStdUiControls10 + Name, new XAttribute("Label", label), new XAttribute("Help", helpDefinition.HelpText), new XElement(Namespaces.BindingForms10 + "bind", new XAttribute("source", bindingSourceName))); } public string Description { get; private set; } public EntityToken EntityToken { get { return new SimpleWidgetFunctionEntityToken(string.Format("{0}.{1}", Namespace, Name)); } } public string Name { get; private set; } public string Namespace { get { return "Composite.Samples.String"; } } public IEnumerable<ParameterProfile> ParameterProfiles { get { yield break; } } public Type ReturnType { get { return typeof(string); } } } [SecurityAncestorProvider(typeof(SimpleAncestorSecurityAncestorProvider))] public class SimpleWidgetFunctionEntityToken : EntityToken { private string _id; internal SimpleWidgetFunctionEntityToken(string id) { _id = id; } public override string Id { get { return _id; } } public override string Source { get { return ""; } } public override string Type { get { return ""; } } // Responsible for serializing the state of this EntityToken as a string public override string Serialize() { return _id; } // Respinsible for deserializing the string return by the serializer above public static EntityToken Deserialize(string serializedEntityToken) { return new SimpleWidgetFunctionEntityToken(serializedEntityToken); } } internal sealed class SimpleAncestorSecurityAncestorProvider : ISecurityAncestorProvider { public IEnumerable<EntityToken> GetParents(EntityToken entityToken) { yield return AttachingPoint.PerspectivesRoot.EntityToken; } } }
Download SimpleTextWidgetFunction.cs - Create a class for the widget provider (e.g. “CustomWidgetFunctionProvider.cs”)
- Add the following code:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Composite.Functions; using Composite.Functions.Plugins.WidgetFunctionProvider; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder; using Microsoft.Practices.ObjectBuilder; namespace Composite.Samples.CustomWidgetProvider { [ConfigurationElementType(typeof(MyWidgetFunctionProviderData))] public class CustomWidgetFunctionProvider : IWidgetFunctionProvider { public IEnumerable<IWidgetFunction> Functions { get { yield return new SimpleTextWidgetFunction("CustomTreeInput", "Sample input widget with a tree picker"); yield return new SimpleTextWidgetFunction("CustomFormInput", "Sample input widget with a form picker"); } } public WidgetFunctionNotifier WidgetFunctionNotifier { set { } } } [Assembler(typeof(MyWidgetFunctionProviderAssembler))] public class MyWidgetFunctionProviderData : WidgetFunctionProviderData { // No custom configuration in this sample... } public sealed class MyWidgetFunctionProviderAssembler : IAssembler<IWidgetFunctionProvider, WidgetFunctionProviderData> { public IWidgetFunctionProvider Assemble(IBuilderContext context, WidgetFunctionProviderData objectConfiguration, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache) { return new CustomWidgetFunctionProvider(); } } }
Download CustomWidgetFunctionProvider.cs - Build the solution.
- Copy the output DLL (e.g. “Composite.Samples.CustomWidgetProvider.dll”) to ~/Bin/ on your website.
Here, in the ‘Functions’ property, both custom controls are specified.
yield return new SimpleTextWidgetFunction("CustomTreeInput", "Sample input widget with a tree picker"); yield return new SimpleTextWidgetFunction("CustomFormInput", "Sample input widget with a form picker");
Comment out the corresponding line if the control is not in use.
Registering the custom control in Composite.config
- Edit
~/App_Data/Composite/Composite.config
- Locate this configuration element:
/configuration/Composite.Functions.Plugins.WidgetFunctionProviderConfiguration/WidgetFunctionProviderPlugins
- Add this element below after the last ‘Add’ element:
<add type="Composite.Samples.CustomWidgetProvider.CustomWidgetFunctionProvider, Composite.Samples.CustomWidgetProvider" name="Composite.Samples.CustomWidgetProvider" />
- Save the file.
Using the custom control with the tree control on a data form
- Create a global data type.
- Add fields making sure at least one of which is of the String type (to be used for the custom control).
- On the Advanced tab of the field, change the default widget to the custom widget (“CustomFormInput” or “CustomTreeInput”).
- Save the changes.