/// <summary>
        /// Handle the drawing attributes changing
        /// </summary>
        /// <param name="sender">The event sender</param>
        /// <param name="args">The event args</param>
        private void HandleDrawingAttributesChanged(object sender, PropertyEventArgs args)
        {
            if (sender == this.m_CurrentStylus && this.m_CurrentStylus != null)
            {
                // Update the bitmap via the CurrentStylusEntry setter.
                this.CurrentStylusEntry = this.m_Table[sender] as StylusEntry;

                using (Synchronizer.Lock(this.m_CurrentStylus.SyncRoot)) {
                    this.Checked = this.CurrentStylusEntry == null ? false
                        : DrawingAttributesToolBarButton.DrawingAttributesEquals(this.m_CurrentStylus.DrawingAttributes, this.CurrentStylusEntry.DrawingAttributes);
                }
            }
            else
            {
                this.Checked = false;
            }
        }
        /// <summary>
        /// Event handler for the drop down opening
        /// </summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The args</param>
        internal virtual void HandleParentButtonDropDown(object sender, EventArgs e)
        {
            if (this.CurrentStylusEntry == null || this.CurrentStylusEntry.DrawingAttributes == null)
            {
                return;
            }
            Form         options = new PropertiesForm.PenPropertiesPage(this.m_Model.PenState, this.CurrentStylusEntry.DrawingAttributes, this.CurrentStylusEntry.PenType == PenType.Pen);
            DialogResult result  = options.ShowDialog();

            // Force an update, since there's no way to change the DrawingAttributes instance.
            this.CurrentStylusEntry = this.CurrentStylusEntry;
            if (this.m_CurrentStylus != null && this.CurrentStylusEntry != null)
            {
                using (Synchronizer.Lock(this.m_CurrentStylus.SyncRoot)) {
                    this.m_CurrentStylus.DrawingAttributes = this.CurrentStylusEntry.DrawingAttributes.Clone();
                }
            }
        }
        /// <summary>
        /// Handle the drawing attributes changing
        /// </summary>
        /// <param name="sender">The event sender</param>
        /// <param name="args">The event arguments</param>
        private void HandleDrawingAttributesChanged(object sender, PropertyEventArgs args)
        {
            if(sender == this.m_CurrentStylus && this.m_CurrentStylus != null) {
                // Update the bitmap via the CurrentStylusEntry setter.
                this.CurrentStylusEntry = this.m_Table[sender] as StylusEntry;

                using(Synchronizer.Lock(this.m_CurrentStylus.SyncRoot)) {
                    this.Checked = this.CurrentStylusEntry == null ? false
                        : DrawingAttributesEquals(this.m_CurrentStylus.DrawingAttributes, this.CurrentStylusEntry.DrawingAttributes);
                }
            } else {
                this.Checked = false;
            }
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="dispatcher">The event queue</param>
        /// <param name="entries">Array of StylusEntries</param>
        /// <param name="model">The presenter model</param>
        /// <param name="parent">The parent ToolStrip</param>
        public DrawingAttributesToolBarButton(ControlEventQueue dispatcher, StylusEntry[] entries, PresenterModel model, ToolStrip parent)
        {
            this.m_EventQueue = dispatcher;
            this.m_Table = new Hashtable();
            this.m_Model = model;
            this.Parent = parent;

            this.templateImage = new Bitmap( Image.FromStream( this.GetType().Assembly.GetManifestResourceStream( "UW.ClassroomPresenter.Viewer.ToolBars.Icons.buttontemplate.png" ) ) );

            foreach(StylusEntry entry in entries)
                this.m_Table.Add(entry.Stylus, entry);

            this.m_DrawingAttributesChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_EventQueue, new PropertyEventHandler(this.HandleDrawingAttributesChanged));
            this.m_StylusChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_EventQueue, new PropertyEventHandler(this.HandleStylusChanged));
            this.m_ColorSetChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_EventQueue, new PropertyEventHandler(this.HandleColorSetChanged));
            this.m_PenWidthChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_EventQueue, new PropertyEventHandler(this.HandlePenWidthChanged));
            this.m_HLWidthChangedDispatcher = new EventQueue.PropertyEventDispatcher(this.m_EventQueue, new PropertyEventHandler(this.HandleHLWidthChanged));

            foreach(StylusModel stylus in this.m_Table.Keys)
                stylus.Changed["DrawingAttributes"].Add(this.m_DrawingAttributesChangedDispatcher.Dispatcher);
            this.m_Model.Changed["Stylus"].Add(this.m_StylusChangedDispatcher.Dispatcher);
            this.m_Model.ViewerState.Changed["UseLightColorSet"].Add(this.m_ColorSetChangedDispatcher.Dispatcher);
            this.m_Model.ViewerState.Changed["DefaultPenWidth"].Add(this.m_PenWidthChangedDispatcher.Dispatcher);
            this.m_Model.ViewerState.Changed["DefaultHLWidth"].Add(this.m_HLWidthChangedDispatcher.Dispatcher);

            // Initialize the Pushed and Enabled states.
            // Note: HandleStylusChanged invokes HandleDrawingAttributesChanged.
            this.m_StylusChangedDispatcher.Dispatcher(this.m_Model, null);

            this.m_ColorSetChangedDispatcher.Dispatcher(this, null);
            this.m_PenWidthChangedDispatcher.Dispatcher(this, null);
        }
        /// <summary>
        /// Event handler for the drop down opening
        /// </summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">The args</param>
        internal virtual void HandleParentButtonDropDown(object sender, EventArgs e)
        {
            if (this.CurrentStylusEntry == null || this.CurrentStylusEntry.DrawingAttributes == null)
                return;
            Form options = new PropertiesForm.PenPropertiesPage(this.m_Model.PenState, this.CurrentStylusEntry.DrawingAttributes, this.CurrentStylusEntry.PenType == PenType.Pen);
            DialogResult result = options.ShowDialog();

            // Force an update, since there's no way to change the DrawingAttributes instance.
            this.CurrentStylusEntry = this.CurrentStylusEntry;
            if (this.m_CurrentStylus != null && this.CurrentStylusEntry != null) {
                using (Synchronizer.Lock(this.m_CurrentStylus.SyncRoot)) {
                    this.m_CurrentStylus.DrawingAttributes = this.CurrentStylusEntry.DrawingAttributes.Clone();
                }
            }
        }