Working on a very simple DataForm control for Winforms I had the need to pass a function delegate to an attribute that qualifies a property to generate a ComboBox on the UI. The function was mean to be used as a way to retrieve the set of values you use to populate the Items property of the ComboBox.
I quickly discovered that I cannot pass that delegate as a parameter using the standard attribute qualifying syntax because: an attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type.
A quick and dirty workaround was to add a Dictionary<String, Func<IEnumerable>> to my DataForm control and a function to actually ‘register’ the delegate you want to use to populate the combox. The delegate is registered using a string key that you will later on pass to the attribute that qualifies the property.
Here are some code snippets taken from the DataForm:
... private readonly Dictionary<string, Func<IEnumerable>> _loadItemsFunctions = new Dictionary<string, Func<IEnumerable>>(); /// <summary> /// Registers the load item function, if a function exists with the same key /// it gets overwritten. /// </summary> /// <param name="key">The key.</param> /// <param name="deleg">The deleg.</param> public void RegisterLoadItemFunc(string key, Func<IEnumerable> deleg) { _loadItemsFunctions[key] = deleg; } ...
and the attribute class:
[AttributeUsage(AttributeTargets.Property)] public class UiHintComboBoxAttribute : Attribute { public UiHintComboBoxAttribute() { DropDownStyle = ComboBoxStyle.DropDownList; BindType = BindTo.SelectedValue; } /// <summary> /// Gets or sets the load items function, it's a string placeholder for a /// function registered in the instance of the control that will use it. /// </summary> /// <value>The load items func.</value> public string LoadItemsFunc { get; set; } public string DisplayMember { get; set; } public string ValueMember { get; set; } public ComboBoxStyle DropDownStyle { get; set; } public BindTo BindType { get; set; } public enum BindTo { SelectedValue, SelectedItem } }
A similar technique can be used if you need to pass descriptive strings along with your attributes and you need to localize those strings: you pass in a reference to a dictionary you populate with phrases in the correct language.
Related Content
- Missing .NET Performance Counters: how to solve it (10/07/2009)
- 19th DotNetMarche Workshop “Community Tour 2011 - CMS Edition” (26/08/2015)
- WebNet European Conference, Slides and Samples (11/06/2012)
- Css and JavaScript file minification (26/08/2015)
- Windows Forms: Closeable TabControl (26/08/2015)
- More related document (7)