|
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Windows.Forms;
namespace DynamicEvents
{
[DefaultEvent("ButtonClick")]
[DefaultProperty("EnumType")]
[Designer(typeof(Design.ButtonContainerDesigner))]
[DesignerSerializer(typeof(Design.DesignEventSerializer), typeof(CodeDomSerializer))]
public partial class ButtonContainer : UserControl
{
public event EventHandler ButtonClick;
public ButtonContainer()
{
InitializeComponent();
}
private Type enumType = typeof(AnchorStyles);
[DefaultValue(typeof(AnchorStyles))]
[TypeConverter(typeof(EnumTypeListConverter))]
public Type EnumType
{
get { return enumType; }
set {
if (value == null)
{
throw new ArgumentNullException();
}
if (!value.IsEnum)
{
throw new ArgumentException();
}
enumType = value;
createButtons();
}
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (enumType == typeof(AnchorStyles))
{
createButtons();
}
}
private void clearButtons()
{
Controls.Clear();
if (eventDictionary != null && eventDictionary.Count > 0)
{
bool clear = false;
foreach (object key in eventDictionary.Keys)
{
if (!Enum.IsDefined(enumType, key))
{
clear = true;
break;
}
}
if (clear)
{
eventDictionary.Clear();
}
}
}
private void createButtons()
{
SuspendLayout();
clearButtons();
int i = 0;
foreach (string name in Enum.GetNames(enumType))
{
Button btn = new Button();
btn.Name = name;
btn.Text = name;
btn.Tag = Enum.Parse(enumType, name);
btn.Location = new Point(3, 3 + i * 31);
btn.Size = new Size(109, 25);
btn.TabIndex = i;
btn.Click += new EventHandler(btn_Click);
Controls.Add(btn);
i++;
}
Size = new Size(115, 6 + Math.Max(Controls.Count, 2) * 31);
ResumeLayout(false);
}
void btn_Click(object sender, EventArgs e)
{
Button btn = (Button) sender;
object value = btn.Tag;
OnButtonClick(btn, value);
OnButtonClick(btn);
}
/// <summary>
/// Raises common <see cref="ButtonClick"/> event.
/// </summary>
private void OnButtonClick(Button sender)
{
if (ButtonClick != null)
{
ButtonClick(sender, EventArgs.Empty);
}
}
#region Seperate Item ButtonClick events
[NonSerialized]
private Dictionary<object, EventHandler> eventDictionary;
public void AddEventHandler(object value, EventHandler listener)
{
if (listener == null)
{
throw new ArgumentNullException("listener");
}
if (!Enum.IsDefined(enumType, value))
{
throw new ArgumentException("Not defined", "value");
}
eventDictionary = eventDictionary ?? new Dictionary<object, EventHandler>();
if (eventDictionary.ContainsKey(value))
{
EventHandler newDel = (EventHandler)Delegate.Combine(eventDictionary[value], listener);
eventDictionary[value] = newDel;
}
else
{
eventDictionary.Add(value, listener);
}
}
public void RemoveEventHandler(object value, EventHandler listener)
{
if (listener == null)
{
throw new ArgumentNullException("listener");
}
if (eventDictionary == null)
{
return;
}
if (!Enum.IsDefined(enumType, value))
{
throw new ArgumentException("Not defined", "value");
}
if (eventDictionary.ContainsKey(value))
{
EventHandler newDel = (EventHandler)Delegate.Remove(eventDictionary[value], listener);
if (newDel != null)
{
eventDictionary[value] = newDel;
}
else
{
eventDictionary.Remove(value);
}
}
}
/// <summary>
/// Raises seperate 'ButtonClick' event for individual item.
/// Raised before common <see cref="ButtonClick"/> event.
/// </summary>
/// <remarks>
/// Listeners are attached by <see cref="AddEventHandler"/> method or designer generated propertygrid events.
/// </remarks>
private void OnButtonClick(Button sender, object value)
{
if (eventDictionary == null)
{
return;
}
if (eventDictionary.ContainsKey(value))
{
EventHandler listener = eventDictionary[value];
listener.Invoke(sender, EventArgs.Empty);
}
}
#endregion
}
#region EnumTypeListConverter
internal enum AssemblyHell
{
one,
two,
three
}
/// <summary>
/// Provides some choices of enum type values.
/// </summary>
public class EnumTypeListConverter : TypeListConverter
{
private static readonly Type[] types = new Type[] { typeof(AnchorStyles), typeof(Appearance), typeof(AssemblyHell) };
public EnumTypeListConverter() : base(types)
{
}
}
#endregion
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.